├── .gitignore ├── .gitlab-ci.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── docs ├── mkdocs.yml └── source │ ├── authors.md │ ├── building.md │ ├── contributing.md │ ├── index.md │ ├── javascripts │ └── config.js │ ├── license.md │ ├── running.md │ └── technical.md ├── examples ├── README.md ├── ethane_water_charge_only │ ├── alchemy_example.py │ ├── equilibrated.pdb │ ├── equilibrated.xml │ ├── ethane_water.xml │ ├── recenter_for_vmd.py │ ├── run_ethane.py │ ├── solvated_ethane_from_openmm_setup.pdb │ ├── trajectory.dcd │ ├── trajectory.nc │ └── trajectory_recentered.dcd ├── parameters │ ├── convert_multipoles.py │ ├── swm4.xml │ ├── swm4_charmm.txt │ ├── swm6.xml │ └── tip3p.xml ├── water_dimer │ ├── mpidwater.xml │ ├── run_water_dimer.py │ ├── waterdimer.pdb │ └── waterdimer_aligned.pdb └── waterbox │ ├── restart.xml │ ├── run.py │ └── waterbox_31ang.pdb ├── openmmapi ├── include │ ├── OpenMMMPID.h │ └── openmm │ │ ├── MPIDForce.h │ │ ├── internal │ │ ├── MPIDForceImpl.h │ │ └── windowsExportMPID.h │ │ └── mpidKernels.h └── src │ ├── MPIDForce.cpp │ └── MPIDForceImpl.cpp ├── platforms ├── cuda │ ├── CMakeLists.txt │ ├── EncodeCUDAFiles.cmake │ ├── include │ │ └── MPIDCudaKernelFactory.h │ ├── src │ │ ├── CudaMPIDKernelSources.cpp.in │ │ ├── CudaMPIDKernelSources.h.in │ │ ├── MPIDCudaKernelFactory.cpp │ │ ├── MPIDCudaKernels.cpp │ │ ├── MPIDCudaKernels.h │ │ └── kernels │ │ │ ├── multipoleElectrostatics.cu │ │ │ ├── multipoleFixedField.cu │ │ │ ├── multipoleInducedField.cu │ │ │ ├── multipolePme.cu │ │ │ ├── multipoles.cu │ │ │ ├── pmeMultipoleElectrostatics.cu │ │ │ ├── sphericalMultipoles.cu │ │ │ └── vectorOps.cu │ └── tests │ │ ├── CMakeLists.txt │ │ └── TestCudaMPIDForce.cpp └── reference │ ├── CMakeLists.txt │ ├── include │ ├── MPIDReferenceKernelFactory.h │ └── windowsExportAmoebaReference.h │ ├── src │ ├── MPIDReferenceKernelFactory.cpp │ ├── MPIDReferenceKernels.cpp │ ├── MPIDReferenceKernels.h │ └── SimTKReference │ │ ├── MPIDReferenceForce.cpp │ │ ├── MPIDReferenceForce.h │ │ ├── jama_cholesky.h │ │ ├── jama_eig.h │ │ ├── jama_lu.h │ │ ├── jama_qr.h │ │ ├── jama_svd.h │ │ ├── tnt.h │ │ ├── tnt_array1d.h │ │ ├── tnt_array1d_utils.h │ │ ├── tnt_array2d.h │ │ ├── tnt_array2d_utils.h │ │ ├── tnt_array3d.h │ │ ├── tnt_array3d_utils.h │ │ ├── tnt_cmat.h │ │ ├── tnt_fortran_array1d.h │ │ ├── tnt_fortran_array1d_utils.h │ │ ├── tnt_fortran_array2d.h │ │ ├── tnt_fortran_array2d_utils.h │ │ ├── tnt_fortran_array3d.h │ │ ├── tnt_fortran_array3d_utils.h │ │ ├── tnt_i_refvec.h │ │ ├── tnt_math_utils.h │ │ ├── tnt_sparse_matrix_csr.h │ │ ├── tnt_stopwatch.h │ │ ├── tnt_subscript.h │ │ ├── tnt_vec.h │ │ └── tnt_version.h │ └── tests │ ├── CMakeLists.txt │ └── TestReferenceMPIDForce.cpp ├── python ├── CMakeLists.txt ├── header.i ├── mpidplugin.i └── setup.py └── serialization ├── include └── openmm │ └── serialization │ └── MPIDForceProxy.h ├── src ├── MPIDForceProxy.cpp └── MPIDSerializationProxyRegistration.cpp └── tests ├── CMakeLists.txt └── TestSerializeMPIDForce.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | MPID.config 3 | MPID.creator 4 | MPID.creator.user 5 | MPID.files 6 | MPID.includes 7 | docs/site 8 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - cudatest 3 | 4 | cudatest: 5 | stage: cudatest 6 | tags: 7 | - cuda 8 | script: 9 | - mkdir -p build_cuda 10 | - cd build_cuda 11 | - rm -rf * 12 | - export PYTHONPATH=`pwd`/src 13 | - export PATH=/v/apps/cmake/3.7.1-centos7/bin:$PATH 14 | - export INTELDIR=/v/apps/intel/composer_xe_2017/compilers_and_libraries_2017.1.132/linux 15 | - export CUDA_HOME=/v/apps/cuda/cuda-7.5.18 16 | - export OPENMM_CUDA_COMPILER=${CUDA_HOME}/bin/nvcc 17 | - export PATH=${CUDA_HOME}/bin:$PATH 18 | - export LM_LICENSE_FILE=/v/apps/intel/licenses/2017_l_PK5BF7J3.lic 19 | - export LD_LIBRARY_PATH=${CUDA_HOME}/lib:${CUDA_HOME}/lib64::${LD_LIBRARY_PATH} 20 | - export INSTALLDIR=`pwd`/testinstall 21 | - export OPENMM_LIB_PATH=${INSTALLDIR}/lib 22 | - export OPENMM_PLUGIN_DIR=${OPENMM_LIB_PATH}/plugins 23 | - export LD_LIBRARY_PATH=${OPENMM_LIB_PATH}:$LD_LIBRARY_PATH 24 | - cp -R /u/andysim/bin/openmm_gitlab_mpid $INSTALLDIR 25 | - source ${INTELDIR}/bin/iccvars.sh intel64 26 | - which python 27 | - which nvcc 28 | - CXX=icpc CC=icc CXXFLAGS='-std=c++11' cmake -DPYTHON_EXECUTABLE=`which python` -DCMAKE_PREFIX_PATH=$INSTALLDIR -DOPENMM_DIR=$INSTALLDIR .. 29 | - make -j2 30 | - ctest -VV 31 | - cd .. 32 | - rm -rf build_cuda 33 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | PROJECT(MPIDOpenMMPlugin) 2 | #--------------------------------------------------- 3 | # OpenMM MPID Plugin 4 | #---------------------------------------------------- 5 | 6 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 7 | 8 | # We need to know where OpenMM is installed so we can access the headers and libraries. 9 | SET(OPENMM_DIR "/usr/local/openmm" CACHE PATH "Where OpenMM is installed") 10 | INCLUDE_DIRECTORIES("${OPENMM_DIR}/include") 11 | LINK_DIRECTORIES("${OPENMM_DIR}/lib" "${OPENMM_DIR}/lib/plugins") 12 | 13 | # set flags for linking on mac 14 | IF(APPLE) 15 | SET (CMAKE_INSTALL_NAME_DIR "@rpath") 16 | SET(EXTRA_COMPILE_FLAGS "-msse2 -stdlib=libc++") 17 | ENDIF(APPLE) 18 | 19 | # Select where to install 20 | IF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) 21 | IF(WIN32) 22 | SET(CMAKE_INSTALL_PREFIX "$ENV{ProgramFiles}/OpenMM" CACHE PATH "Where to install the plugin" FORCE) 23 | ELSE(WIN32) 24 | SET(CMAKE_INSTALL_PREFIX "/usr/local/openmm" CACHE PATH "Where to install the plugin" FORCE) 25 | ENDIF(WIN32) 26 | ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) 27 | 28 | # The source is organized into subdirectories, but we handle them all from 29 | # this CMakeLists file rather than letting CMake visit them as SUBDIRS. 30 | SET(MPID_PLUGIN_SOURCE_SUBDIRS openmmapi serialization) 31 | 32 | # Set the library name 33 | SET(MPID_LIBRARY_NAME MPIDPlugin) 34 | SET(SHARED_MPID_TARGET ${MPID_LIBRARY_NAME}) 35 | 36 | # These are all the places to search for header files which are to be part of the API. 37 | SET(API_INCLUDE_DIRS "openmmapi/include" "openmmapi/include/internal") 38 | 39 | # Locate header files. 40 | SET(API_INCLUDE_FILES) 41 | FOREACH(dir ${API_INCLUDE_DIRS}) 42 | FILE(GLOB fullpaths ${dir}/*.h) 43 | SET(API_INCLUDE_FILES ${API_INCLUDE_FILES} ${fullpaths}) 44 | ENDFOREACH(dir) 45 | 46 | # Collect up source files 47 | SET(SOURCE_FILES) # empty 48 | SET(SOURCE_INCLUDE_FILES) 49 | FOREACH(subdir ${MPID_PLUGIN_SOURCE_SUBDIRS}) 50 | FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp) 51 | FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h) 52 | SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append 53 | SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) 54 | 55 | ## Make sure we find these locally before looking in OpenMM/include if 56 | ## OpenMM was previously installed there. 57 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include) 58 | ENDFOREACH(subdir) 59 | 60 | # Create the library. 61 | 62 | ADD_LIBRARY(${SHARED_MPID_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_INCLUDE_FILES}) 63 | SET_TARGET_PROPERTIES(${SHARED_MPID_TARGET} 64 | PROPERTIES COMPILE_FLAGS "-DMPID_BUILDING_SHARED_LIBRARY ${EXTRA_COMPILE_FLAGS}" 65 | LINK_FLAGS "${EXTRA_COMPILE_FLAGS}") 66 | TARGET_LINK_LIBRARIES(${SHARED_MPID_TARGET} OpenMM) 67 | INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${SHARED_MPID_TARGET}) 68 | 69 | # install headers 70 | FILE(GLOB API_ONLY_INCLUDE_FILES "openmmapi/include/*.h") 71 | INSTALL (FILES ${API_ONLY_INCLUDE_FILES} DESTINATION include) 72 | FILE(GLOB API_ONLY_INCLUDE_FILES_INTERNAL "openmmapi/include/internal/*.h") 73 | INSTALL (FILES ${API_ONLY_INCLUDE_FILES_INTERNAL} DESTINATION include/internal) 74 | 75 | # Enable testing 76 | 77 | ENABLE_TESTING() 78 | 79 | set(BUILD_TESTING ON CACHE BOOL "Build tests") 80 | set(OPENMM_BUILD_REFERENCE_TESTS ON CACHE BOOL "Build reference platform tests") 81 | ADD_SUBDIRECTORY(serialization/tests) 82 | 83 | # Build the implementations for different platforms 84 | 85 | ADD_SUBDIRECTORY(platforms/reference) 86 | 87 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}") 88 | 89 | FIND_PACKAGE(CUDA QUIET) 90 | IF(CUDA_FOUND) 91 | SET(MPID_BUILD_CUDA_LIB ON CACHE BOOL "Build implementation for CUDA") 92 | ELSE(CUDA_FOUND) 93 | SET(MPID_BUILD_CUDA_LIB OFF CACHE BOOL "Build implementation for CUDA") 94 | ENDIF(CUDA_FOUND) 95 | IF(MPID_BUILD_CUDA_LIB) 96 | ADD_SUBDIRECTORY(platforms/cuda) 97 | ENDIF(MPID_BUILD_CUDA_LIB) 98 | 99 | # Build the Python API 100 | 101 | FIND_PROGRAM(PYTHON_EXECUTABLE python) 102 | FIND_PROGRAM(SWIG_EXECUTABLE swig) 103 | IF(PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) 104 | SET(MPID_BUILD_PYTHON_WRAPPERS ON CACHE BOOL "Build wrappers for Python") 105 | ELSE(PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) 106 | SET(MPID_BUILD_PYTHON_WRAPPERS OFF CACHE BOOL "Build wrappers for Python") 107 | ENDIF(PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) 108 | IF(MPID_BUILD_PYTHON_WRAPPERS) 109 | ADD_SUBDIRECTORY(python) 110 | ENDIF(MPID_BUILD_PYTHON_WRAPPERS) 111 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2021, Andrew C. Simmonett 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | This plugin implements polarizable multipole electrostatics, primarily aimed at 4 | supporting the [MPID](https://doi.org/10.1063/1.4984113) formulation of the 5 | CHARMM Drude force field. The code supports multipoles up to octopoles, as 6 | well as induced dipoles that may be either isotropic or anisotropic. 7 | 8 | # Documentation 9 | 10 | The user manual describing usage and technical aspects of the code can be found 11 | [here](https://andysim.github.io/MPIDOpenMMPlugin/). 12 | 13 | # License 14 | 15 | The code is distributed freely under the terms of the BSD 3 clause license, 16 | which can be found in the top level directory of this repository. 17 | -------------------------------------------------------------------------------- /docs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: MPIDOpenMMPlugin Documentation and Notes 2 | markdown_extensions: 3 | - pymdownx.arithmatex: 4 | generic: true 5 | 6 | extra_javascript: 7 | - javascripts/config.js 8 | - https://polyfill.io/v3/polyfill.min.js?features=es6 9 | - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 10 | 11 | nav: 12 | - Home: index.md 13 | - Installation: building.md 14 | - Running the Code: running.md 15 | - Technical Details: technical.md 16 | - Contributing: contributing.md 17 | - License: license.md 18 | - Authors: authors.md 19 | 20 | theme: readthedocs 21 | 22 | docs_dir: source 23 | -------------------------------------------------------------------------------- /docs/source/authors.md: -------------------------------------------------------------------------------- 1 | The plugin was written by Andrew C. Simmonett at the National Institutes of 2 | Health, and was based on the AMOEBA plugin written by Mark Friedrichs and Peter 3 | Eastman at Stanford. 4 | -------------------------------------------------------------------------------- /docs/source/building.md: -------------------------------------------------------------------------------- 1 | # Obtaining the code 2 | 3 | The plugin is hosted [on Github](https://github.com/andysim/MPIDOpenMMPlugin) and can be checked out with 4 | ``` bash 5 | git clone git@github.com:andysim/MPIDOpenMMPlugin 6 | ``` 7 | 8 | # Dependencies 9 | 10 | The code needs OpenMM version 7.6 or later (tested with 7.7), which can be 11 | installed as follows. 12 | 13 | ## Installation of Dependencies via Conda 14 | 15 | Conda is *strongly* recommended for managing the environment and dependencies; 16 | after [downloading](https://conda.io/docs/download.html) anaconda (make sure 17 | you use `bash` or `zsh`). 18 | 19 | To install the 7.7 verion of OpenMM into its own Conda environment called `mpid`, run 20 | ``` bash 21 | conda create -n mpid openmm=7.7 cudatoolkit=10.2 swig mdtraj -c conda-forge 22 | ``` 23 | Make sure you request the version of the CUDA toolkit supported on your 24 | cluster. This example uses GCC to build; the speed of the C++ compiler is 25 | irrelevant, because the CUDA code is the only fast code available in this 26 | plugin. Although the reference platform will run, it is very slow and 27 | designed for correctness. 28 | 29 | ## Building the plugin 30 | 31 | The plugin uses CMake for building, so that should be install locally; it can 32 | be obtained from Conda if you do not have it available. Once CMake is 33 | installed, you can build the code using commands similar to the following (the 34 | exact type of modules and mechanisms to load them will vary from system to 35 | system):: 36 | 37 | ``` bash 38 | conda activate mpid 39 | 40 | export OPENMM_INSTALL_DIR=~/anaconda3/envs/mpid 41 | 42 | module load cuda/10.2 43 | module load cmake 44 | module load gcc/8.2 45 | 46 | # From the MPIDOpenMMPlugin top level directory 47 | mkdir build 48 | cd build 49 | CXX=g++ cmake .. -DCMAKE_INSTALL_PREFIX=$OPENMM_INSTALL_DIR -DPYTHON_EXECUTABLE=`which python` -DOPENMM_DIR=$OPENMM_INSTALL_DIR -DCMAKE_CXX_FLAGS='-std=c++11' 50 | make -j 4 51 | make test 52 | make install 53 | make PythonInstall 54 | ``` 55 | Note that we use GCC in this example, but the nature of the C++ compiler is not 56 | important, as the faster kernels are implemented in CUDA and only the slow 57 | reference implementation is available on regular CPUs. 58 | 59 | Before running the code, make sure you load the conda environment and all 60 | modules used for building when using the plugin. 61 | ``` bash 62 | conda activate mpid 63 | ``` 64 | -------------------------------------------------------------------------------- /docs/source/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The code is fully open source, and contributions are welcome via a pull request 4 | on Github. Please open an issue on Github to report any problems. 5 | -------------------------------------------------------------------------------- /docs/source/index.md: -------------------------------------------------------------------------------- 1 | #About 2 | 3 | This [OpenMM](https://openmm.org/) plugin implements polarizable multipole electrostatics, primarily aimed at 4 | supporting the [MPID](https://doi.org/10.1063/1.4984113) formulation of the 5 | CHARMM Drude force field. However, the code is quite general and many features 6 | can be compiled on-the-fly, allowing it to tailor features as required without 7 | incurring a performance penalty. 8 | 9 | Supported features include: 10 | 11 | * Particle mesh Ewald electrostatics. 12 | * Multipoles (up to octopoles). 13 | * Induced dipoles, with a range of solvers to evaluate them. 14 | * Isotropic or anisotropic polarizability. 15 | -------------------------------------------------------------------------------- /docs/source/javascripts/config.js: -------------------------------------------------------------------------------- 1 | window.MathJax = { 2 | tex: { 3 | inlineMath: [["\\(", "\\)"]], 4 | displayMath: [["\\[", "\\]"]], 5 | processEscapes: true, 6 | processEnvironments: true 7 | }, 8 | options: { 9 | ignoreHtmlClass: ".*|", 10 | processHtmlClass: "arithmatex" 11 | } 12 | }; 13 | 14 | document$.subscribe(() => { 15 | MathJax.typesetPromise() 16 | }) 17 | -------------------------------------------------------------------------------- /docs/source/license.md: -------------------------------------------------------------------------------- 1 | This plugin is freely distributed under the BSD 3-Clause License: 2 | 3 | ``` text 4 | Copyright (c) 2017-2021, Andrew C. Simmonett 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/source/running.md: -------------------------------------------------------------------------------- 1 | # Running the Plugin 2 | 3 | The following is a brief summary of the [simple 4 | examples](https://github.com/andysim/MPIDOpenMMPlugin/tree/master/examples) 5 | included in the repository. The usage of the plugin follows [standard OpenMM 6 | practices](http://docs.openmm.org/latest/userguide/index.htmlr)] so that would 7 | be a good place to start for anybody unfamiliar with OpenMM. 8 | 9 | ## Specifying the Parameters 10 | 11 | ### Units 12 | 13 | OpenMM uses the following units: 14 | 15 | - Time: $ps$ 16 | - Energy: $kJ/mol$ 17 | - Distance: $nm$ 18 | - Mass: $amu$ 19 | - Temperature: $K$ 20 | - Charge: $e$ 21 | - Angle: $rad$ 22 | 23 | This choice ensures that forces obtained from $F=ma$ are consistent with those 24 | obtained from $F=-\frac{\mathrm{d}U}{\mathrm{d}R}$ without the need for scale 25 | factors. 26 | 27 | ## The XML file 28 | 29 | Parameters should be specified using a standard [OpenMM XML 30 | file](http://docs.openmm.org/latest/userguide/application.html#writing-the-xml-file). 31 | As an illustrative example, here is the full specification of the MPID 32 | implementation of the [SWM6](https://doi.org/10.1063/1.4774577) water model: 33 | 34 | ``` xml 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 72 | 73 | 74 | 75 | 76 | ``` 77 | 78 | Most of this file sets up bonded terms, which are well described in the OpenMM 79 | documentation linked above. When defining the `NonbondedForce`, note that the 80 | charges are defined as zero; this is because all electrostatic terms are to be 81 | handled by the `MPIDForce`. The `MPIDForce` does not handle Lennard-Jones (LJ) 82 | terms, so these are still processed by the `NonbondedForce`, which can also use 83 | particle mesh Ewald (PME) to compute the LJ terms effectively without cutoffs. 84 | The section defining the `MPIDForce` terms looks like this: 85 | 86 | ``` xml 87 | 88 | 94 | 100 | 101 | 102 | 103 | ``` 104 | 105 | The global `coulomb14scale` parameter controls the scale factor applied to 106 | interactions that are topologically three bonds apart, and defaults to 1 (the 107 | correct value for MPID) if omitted. The `defaultTholeWidth` parameter is the 108 | [Thole damping] (technical.md#thole-damping) parameter that's applied to 109 | particles whose interaction is not neglected due to topological reasons. 110 | 111 | Multipoles are defined by providing orientation rules, defining their 112 | orientation with respect to "anchor" atoms within the same system and the 113 | syntax follows the [conventions 114 | used](https://pubs.acs.org/doi/10.1021/ct200304d) in the AMOEBA force field. 115 | For example, `Multipole type="OT" kz="-HT" kx="-HT"` defines a multipole on the 116 | `OT` atom, whose z direction is defined as the bisector of the two `HT` atoms 117 | directly connected to it, with the $x$ direction defined by the plane 118 | containing both `HT`. The `Multipole type="HT" kz="OT" kx="HT"` similarly 119 | defines a multipole on `HT`, whose local `z` axis is defined by its bond to the 120 | `OT` atom; the $x$ axis is then defined by the plane containing the other `HT` 121 | atom. 122 | 123 | The `c0` entry defines the charge (in $e$), while `dX` defines the $x$ 124 | component of the dipole in $e/nm$, _etc._. Multipoles up to octopoles are 125 | supported, and any values omitted are assumed to be zero. 126 | 127 | The `Polarize` tag is optional and is used to define a given atom as 128 | polarizable. The $xx$, $yy$ and $zz$ elements of the polarizability tensor 129 | should be specified individually, in the axis system used to define the 130 | multipoles described above. If all three components of the polarizability 131 | tensor are equal, the polarizability is isotropic and the orientation rules are 132 | irrelevant. The Thole damping parameter, [detailed 133 | here](technical.md#thole-damping) is a unitless parameter used to dampen 134 | topologically excluded interactions between pairs of induced dipoles if the 135 | chosen solver considers them. 136 | 137 | ## Creating a System 138 | 139 | With the appropriate XML-formatted force field in hand, setting up a simulation 140 | follows the [standard OpenMM 141 | approach](http://docs.openmm.org/latest/userguide/application.html#a-first-example). 142 | The `createSystem()` function from the `ForceField` class, which is used to 143 | build the system obeys all of the [usual 144 | arguments](http://docs.openmm.org/development/api-python/generated/openmm.app.forcefield.ForceField.html#openmm.app.forcefield.ForceField.createSystem) 145 | for controlling constraint algorithms, hydrogen mass repartitioning, 146 | cutoffs, _etc._. For `MPIDForce`, the `defaultTholeWidth` and 147 | `coulomb14scale` arguments may be provided, overriding any values that may be 148 | present in the XML parameter file described above. The `polarization` argument 149 | is used to control the [polarization solver](technical.md#solvers). 150 | -------------------------------------------------------------------------------- /docs/source/technical.md: -------------------------------------------------------------------------------- 1 | # Polarization 2 | 3 | The induced dipoles are the solution to the $3N\times3N$ system of equations 4 | 5 | $$ 6 | \boldsymbol{\mu}_\mathrm{ind} = \mathbf{T}^{-1} \mathbf{E} 7 | $$ 8 | 9 | where the electric field due to fixed multipoles is $\mathbf{E}$ and the 10 | coupling matrix 11 | 12 | $$ 13 | \mathbf{T} = \boldsymbol{\alpha}^{-1} + \boldsymbol{\tau} 14 | $$ 15 | 16 | is given by the inverse of the diagonal matrix of atomic polarizabilities and the 17 | off-diagonal matrix that couples pairs of induced dipoles. When generating the 18 | permanent field $\mathbf{E}$, topologically excluded (1-2 and 1-3) interactions 19 | are neglected, and any 1-4 interactions are scaled, if requested. All pairs of 20 | induced dipoles are allowed to interact, which is a key feature of the damping 21 | procedure described below. 22 | 23 | ## Solvers 24 | 25 | A few solvers are implemented for evaluating the induced dipoles, which we will 26 | briefly discuss. These can be selected by passing the appropriate string to 27 | the `polarization` argument of `createSystem()`. 28 | 29 | ### Direct Solver 30 | 31 | The simplest "direct" solver simply uses the approximation 32 | 33 | $$ 34 | \mathbf{T} \approx \boldsymbol{\alpha}^{-1} 35 | $$ 36 | 37 | which effectively removes the mutual interaction between induced dipoles. 38 | Because $\boldsymbol{\alpha}$ is diagonal, it is trivially invertible and the 39 | solution is fully analytic. As a result, the energies and forces are 40 | rigorously consistent and integration can be performed exactly as for 41 | conventional fixed point charges. However, this simplicity comes at the 42 | expense of the quality of the description of the electrostatics. 43 | 44 | ### Mutual Solver 45 | 46 | The "mutual" solver keeps the interaction between induced dipoles, making 47 | $\mathbf{T}$ difficult to invert. The induced dipole equations are solved 48 | iteratively, with the convergence accelerated by the direct inversion of the 49 | iterative subspace (DIIS) technique. Because the coupling between dipoles is 50 | present this is the most accurate method, but it is also the most costly due to 51 | the need for multiple iterations to solve the equations. While it might be 52 | tempting for to lower the convergence criterion to save time, this will lead to 53 | inconsistencies in the energies and forces, and runaway heating (or cooling) of 54 | the microcanonical ensemble will result. We recommend converging the equation 55 | to at least $10^{-4}$ if using this solver; the convergence is controlled by 56 | the `mutualInducedTargetEpsilon` argument to `createSystem()`, with a 57 | default value of $10^{-5}$. 58 | 59 | ### Extrapolated Solver 60 | 61 | Combining the strengths of both approaches, the $n$th order Optimized 62 | Perturbation Theory [OPTn](http://dx.doi.org/10.1063/1.4964866) solver treats 63 | the induced dipole coupling matrix as a small perturbation to the "direct" 64 | model, leading to a power series expansion that can be truncated at any order. 65 | Some empirical tuning yields the OPT$n$ family of methods. At zeroth order, 66 | the "direct" solution is obtained. Successively increasing the order increases 67 | the cost, with each order costing the equivalent of an iteration of the 68 | "mutual" solver. Unlike loosely converged "mutual" solutions, the OPT$n$ 69 | solutions have energies and forces that are rigorously consistent at all levels 70 | of trunctions. We recommend the third order "extrapolated" solver, OPT3, which 71 | is the default solver in this plugin. Other levels of OPT solver may be 72 | selected by calling the `setExtrapolationCoefficients()` on the `MPIDForce` 73 | object. 74 | 75 | ##Thole Damping 76 | 77 | If a pair of polarizable particles get too close, they can strongly polarize 78 | each other and at some distance this overpolarization will become infinite; 79 | this is often refered to as the "polarization catastrophe". Thole 80 | [introduced](https://doi.org/10.1016/0301-0104(81)85176-2) a clever damping 81 | that effectively gives the point dipoles a finite width and removes the 82 | singularity responsible for terms blowing up at short range. The density 83 | ascribed to MPID's induced dipoles corresponds to Thole's $\rho_1$ choice (in 84 | contrast to AMOEBA, which uses $\rho_2$): 85 | 86 | $$ 87 | \rho_1 = \frac{a^3}{8\pi}e^{-a u} 88 | $$ 89 | 90 | where $a$ is a unitless width parameter and $u$ is a dimensionless distance. 91 | The result of introducing this density is that interactions between a pair of 92 | induced dipoles is scaled by a factor 93 | 94 | $$ 95 | 1 - e^{-a u}(1 + au + \frac{(a u)^2}{2}). 96 | $$ 97 | 98 | For [MPID](https://doi.org/10.1063/1.4984113), the dimensionless distance for a 99 | pair of interacting atoms $i$ and $j$ is given by their separation, $R_{ij}$, 100 | and the individual atomic polarizabilities $\alpha_i$ and $\alpha_j$ by 101 | 102 | $$ 103 | u = \frac{R_{ij}}{\alpha_i\alpha_j}. 104 | $$ 105 | 106 | If the polarizability of and atom is anisotropic, the average of the three 107 | diagonal tensor elements is used. The dimensionless width parameter $a$ is 108 | given a default value that is used for any interaction that is not excluded 109 | (1-2, 1-3 and, if `coulomb14scale` is zero, 1-4 connected pairs); this default 110 | value is controlled by the `defaultTholeWidth` argument to either the XML force 111 | field file or `createSystem()`. The excluded interactions do not contribute to 112 | permanent-permenent moment interactions, or to forming the electric field 113 | $\mathbf{E}$ used to define the induced dipoles. For `mutual` and 114 | `extrapolated` solvers, the induced dipoles are allowed to interact with each 115 | other. These interactions are not subject to excluded rules. For pairs that 116 | are not excluded due to topology, the `defaultTholeWidth` parameter is used to 117 | define $a$. For pairs that are excluded due to topology, we use the individual 118 | Thole widths defined in the parameter file and define $a=a_i + a_j$. 119 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | Illustrative Examples 2 | ================ 3 | This folder contains some simple snippets to show how the MPID plugin can be 4 | used. 5 | 6 | waterbox 7 | ------------ 8 | This is a ~31 Å waterbox, holding 996 water molecules. It is set up to be able 9 | to run the standard TIP3P model, as well as the analytic MPID variants of the 10 | SWM4 and SWM6 Drude water models. 11 | 12 | water_dimer 13 | ---------------- 14 | This is a simple water dimer, whose intermolecular distance can be varied to 15 | directly study the difference between the Drude and MPID models. 16 | 17 | ethane_water_charge_only 18 | --------------------------------- 19 | A single ethane molecule in a 35 Å box containing 1383 water molecules. The 20 | initial PDB file was constructed using `openmm-setup` and the XML parameters 21 | were extracted from the CHARMM36 parameter file that ships with OpenMM, with 22 | arbitrarily chosen polarizability settings assigned to the heavy atoms. The 23 | `run_ethane.py` example runs a short trajectory of this system, while the 24 | `alchemy_example.py` file demonstrates how to make alchemical changes to the 25 | ethane molecule to allow it to disappear in the water box. 26 | -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/alchemy_example.py: -------------------------------------------------------------------------------- 1 | from openmm.app import * 2 | from openmm import * 3 | from openmm.unit import * 4 | import openmm.app.element as elem 5 | from sys import stdout, argv 6 | import mpidplugin 7 | import numpy as np 8 | from mdtraj.reporters import NetCDFReporter 9 | 10 | pdb = PDBFile('solvated_ethane_from_openmm_setup.pdb') 11 | forcefield = ForceField('ethane_water.xml') 12 | system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, polarization='direct', 13 | nonbondedCutoff=8*angstrom, constraints=HBonds, defaultTholeWidth=8) 14 | temperature = 298*kelvin 15 | system.addForce(MonteCarloBarostat(1*atmosphere, temperature, 25)) 16 | integrator = LangevinIntegrator(temperature, 1/picosecond, 2*femtoseconds) 17 | 18 | try: 19 | myplatform = Platform.getPlatformByName('CUDA') 20 | # Figure out which GPU to run on, i.e. did the user tell us? 21 | deviceid = argv[1] if len(argv) > 1 else '0' 22 | #myproperties = {'DeviceIndex': deviceid, 'Precision': 'double'} 23 | myproperties = {'DeviceIndex': deviceid, 'Precision': 'mixed'} 24 | except: 25 | print("CUDA NOT FOUND!!!!!!!!!!") 26 | myplatform = None 27 | deviceid = "N/A" 28 | 29 | if myplatform: 30 | simulation = Simulation(pdb.topology, system, integrator, myplatform, myproperties) 31 | else: 32 | simulation = Simulation(pdb.topology, system, integrator) 33 | 34 | context = simulation.context 35 | if pdb.topology.getPeriodicBoxVectors(): 36 | context.setPeriodicBoxVectors(*pdb.topology.getPeriodicBoxVectors()) 37 | 38 | print("Running on ", context.getPlatform().getName(), " Device ID:", deviceid) 39 | 40 | # Initialize 41 | context.setPositions(pdb.positions) 42 | #simulation.loadState('equilibrated.xml') 43 | 44 | # Get a list of the forces. We use a dictionary here because there is only one force present 45 | # that identifies itself as just a "Force". If multiple plugins are used, this needs to change. 46 | forces = {system.getForce(i).__class__.__name__: system.getForce(i) for i in range(system.getNumForces())} 47 | if mpidplugin.MPIDForce.isinstance(forces['Force']): 48 | mpidforce = mpidplugin.MPIDForce.cast(forces['Force']) 49 | else: 50 | raise "Unknown custom force detected!" 51 | 52 | print(f'initial energy = ',context.getState(getEnergy=True).getPotentialEnergy()) 53 | 54 | # Specify lambda windows for alchemical changes 55 | lambdas = np.arange(0.0, 1.05, 0.1) 56 | selection = range(8) # We know the first 8 atoms are ethane 57 | 58 | # Turn on the electrostatic terms in increments, after storing the initial values 59 | # Order of parameters is 60 | # charge, dipole, qpole, opole, axis, atomZ, atomX, atomY, thole, alphas 61 | elec_params = [ mpidforce.getMultipoleParameters(i) for i in selection ] 62 | 63 | for lam in lambdas: 64 | for i in selection: 65 | params = elec_params[i].copy() 66 | # charge 67 | params[0] *= lam 68 | # dipoles 69 | params[1] = [d * lam for d in params[1]] 70 | # quadrupoles 71 | params[2] = [q * lam for q in params[2]] 72 | # octopoles 73 | params[3] = [o * lam for o in params[3]] 74 | # polarizabilities 75 | params[9] = [a * lam for a in params[9]] 76 | mpidforce.setMultipoleParameters(i, *params) 77 | mpidforce.updateParametersInContext(context) 78 | print(f'elec lambda = {lam:.2f}, energy = ',context.getState(getEnergy=True).getPotentialEnergy()) 79 | 80 | # Turn on the VDW terms in increments, after storing the initial values 81 | # Order of paramters is 82 | # charge, sigma, epsilon 83 | vdw_params = [ forces['NonbondedForce'].getParticleParameters(i) for i in selection ] 84 | 85 | for lam in lambdas: 86 | for i in selection: 87 | params = [lam*p for p in vdw_params[i]] 88 | forces['NonbondedForce'].setParticleParameters(i, *params) 89 | forces['NonbondedForce'].updateParametersInContext(context) 90 | print(f'vdw lambda = {lam:.2f}, energy = ',context.getState(getEnergy=True).getPotentialEnergy()) 91 | 92 | # Make sure the final energy is the same as the original (unperturbed) value, with roundoff error 93 | print(f'final energy = ',context.getState(getEnergy=True).getPotentialEnergy()) 94 | -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/equilibrated.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andysim/MPIDOpenMMPlugin/2096a0dd548575e0c05c69b4fc5507a51089e1b9/examples/ethane_water_charge_only/equilibrated.pdb -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/ethane_water.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 77 | -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/recenter_for_vmd.py: -------------------------------------------------------------------------------- 1 | import mdtraj as md 2 | 3 | # A simple script to recenter a trajetory so that it appears correctly in VMD 4 | traj = md.load("trajectory.dcd", top="solvated_ethane_from_openmm_setup.pdb") 5 | traj.center_coordinates() 6 | traj.save_dcd("trajectory_recentered.dcd") 7 | -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/run_ethane.py: -------------------------------------------------------------------------------- 1 | from openmm.app import * 2 | from openmm import * 3 | from openmm.unit import * 4 | import openmm.app.element as elem 5 | from sys import stdout, argv 6 | import mpidplugin 7 | import numpy as np 8 | from mdtraj.reporters import NetCDFReporter 9 | 10 | pdb = PDBFile('solvated_ethane_from_openmm_setup.pdb') 11 | forcefield = ForceField('ethane_water.xml') 12 | system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, polarization='direct', 13 | nonbondedCutoff=8*angstrom, constraints=HBonds, defaultTholeWidth=8) 14 | temperature = 298*kelvin 15 | system.addForce(MonteCarloBarostat(1*atmosphere, temperature, 25)) 16 | integrator = LangevinIntegrator(temperature, 1/picosecond, 2*femtoseconds) 17 | 18 | # Make sure all the forces we expect are present 19 | for force in range(system.getNumForces()): 20 | print(system.getForce(force)) 21 | 22 | try: 23 | myplatform = Platform.getPlatformByName('CUDA') 24 | # Figure out which GPU to run on, i.e. did the user tell us? 25 | deviceid = argv[1] if len(argv) > 1 else '0' 26 | myproperties = {'DeviceIndex': deviceid, 'Precision': 'mixed'} 27 | except: 28 | print("CUDA NOT FOUND!!!!!!!!!!") 29 | myplatform = None 30 | deviceid = "N/A" 31 | 32 | if myplatform: 33 | simulation = Simulation(pdb.topology, system, integrator, myplatform, myproperties) 34 | else: 35 | simulation = Simulation(pdb.topology, system, integrator) 36 | 37 | context = simulation.context 38 | if pdb.topology.getPeriodicBoxVectors(): 39 | context.setPeriodicBoxVectors(*pdb.topology.getPeriodicBoxVectors()) 40 | 41 | print("Running on ", context.getPlatform().getName(), " Device ID:", deviceid) 42 | 43 | # Initialize 44 | context.setPositions(pdb.positions) 45 | if os.path.isfile('equilibrated.xml'): 46 | simulation.loadState('equilibrated.xml') 47 | 48 | # Dump trajectory info every 10ps 49 | #simulation.reporters.append(DCDReporter('trajectory.dcd', 5000)) 50 | simulation.reporters.append(NetCDFReporter('trajectory.nc', 5000)) 51 | nsteps = 250000 52 | simulation.reporters.append(StateDataReporter(stdout, 500, totalSteps=nsteps, speed=True, volume=True, density=True, 53 | step=True, potentialEnergy=True, totalEnergy=True, temperature=True)) 54 | simulation.reporters.append(PDBReporter('equilibrated.pdb', nsteps)) 55 | # Run 0.5ns of simulation 56 | simulation.step(nsteps) 57 | simulation.saveState('equilibrated.xml') 58 | -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/trajectory.dcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andysim/MPIDOpenMMPlugin/2096a0dd548575e0c05c69b4fc5507a51089e1b9/examples/ethane_water_charge_only/trajectory.dcd -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/trajectory.nc: -------------------------------------------------------------------------------- 1 | CDF -------------------------------------------------------------------------------- /examples/ethane_water_charge_only/trajectory_recentered.dcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andysim/MPIDOpenMMPlugin/2096a0dd548575e0c05c69b4fc5507a51089e1b9/examples/ethane_water_charge_only/trajectory_recentered.dcd -------------------------------------------------------------------------------- /examples/parameters/convert_multipoles.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | bohr = 0.52917720859 3 | dCon = 0.1*bohr 4 | qCon = 0.01*bohr*bohr/3.0 5 | oCon = 0.001*bohr*bohr*bohr/15.0 6 | sf = 3*[dCon]+6*[qCon]+10*[oCon] 7 | 8 | SWMO = list(map(float, "0.00000 0.00000 -0.50626 0.11497 0.00000 0.11497 0.00000 0.00000 -0.22994 0.00000 0.00000 0.00000 0.00000 0.05222 0.00000 0.05222 0.00000 0.00000 -0.10443".split())) 9 | 10 | def prettyprint(atomlabel, vals): 11 | vals = np.multiply(sf, vals) 12 | X = vals[0] 13 | Y = vals[1] 14 | Z = vals[2] 15 | XX = vals[3] 16 | XY = vals[4] 17 | YY = vals[5] 18 | XZ = vals[6] 19 | YZ = vals[7] 20 | ZZ = vals[8] 21 | opoles = vals[9:] 22 | XXX = opoles[0] 23 | XXY = opoles[1] 24 | XYY = opoles[2] 25 | YYY = opoles[3] 26 | XXZ = opoles[4] 27 | XYZ = opoles[5] 28 | YYZ = opoles[6] 29 | XZZ = opoles[7] 30 | YZZ = opoles[8] 31 | ZZZ = opoles[9] 32 | print('dX="%.10g" dY="%.10g" dZ="%.10g"' % (X, Y, Z)) 33 | print('qXX="%.10g" qXY="%.10g" qXZ="%.10g" qYY="%.10g" qYZ="%.10g" qZZ="%.10g"' % (XX, XY, XZ, YY, YZ, ZZ)) 34 | print('oXXX="%.10g" oXXY="%.10g" oXYY="%.10g" oYYY="%.10g" oXXZ="%.10g" oXYZ="%.10g" oYYZ="%.10g" oXZZ="%.10f" oYZZ="%.10g" oZZZ="%.10g"' % (XXX, XXY, XYY, YYY, XXZ, XYZ, YYZ, XZZ, YZZ, ZZZ)) 35 | 36 | prettyprint('o', SWMO) 37 | -------------------------------------------------------------------------------- /examples/parameters/swm4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/parameters/swm4_charmm.txt: -------------------------------------------------------------------------------- 1 | RESI SWM4 0.000 2 | GROUP 3 | ATOM OH2 ODW -1.11466 4 | ATOM H1 HDW 0.55733 5 | ATOM H2 HDW 0.55733 6 | 7 | POLARIZE OH2 0.97825258 1.3 8 | 9 | BOND OH2 H1 10 | BOND OH2 H2 11 | BOND H1 H2 12 | 13 | 14 | OPOLE OH2 BISECT OH2 H1 H2 - 15 | 0.00000 0.00000 -0.50626 - 16 | 0.11497 0.00000 0.11497 0.00000 0.00000 -0.22994 - 17 | 0.00000 0.00000 0.00000 0.00000 0.05222 0.00000 0.05222 0.00000 0.00000 -0.10443 18 | 19 | ACCEPTOR OH2 20 | PATCH FIRST NONE LAST NONE 21 | 22 | read para card !append 23 | * Drude polarizable FF parameters 24 | * 25 | 26 | BONDS 27 | !atom type Kb b0 28 | !============================================ 29 | ! 30 | ODW LPDW 0.00 0.24034492 ! SWM4, SWM4-NDP water, Guillaume 2005 31 | X DRUD 500.00 0.000 ! DO NOT COMMENT. Essential for use of Drudes in c41b1. Bug... 32 | ODW HDW 450.00 0.9572 ! SWM4, SWM4-NDP water, Guillaume 2005 33 | ODW DOH2 500.00 0.0000 ! SWM4, SWM4-NDP water, Guillaume 2005 34 | HDW HDW 0.00 1.5139 ! SWM4 and SWM6 water models 35 | 36 | ANGLES 37 | !atom types Ktheta Theta0 Kub S0 38 | !================================================== 39 | HDW ODW HDW 55.000 104.52 ! SWM4-NDP water Guillaume 2005 40 | 41 | DIHEDRALS 42 | 43 | IMPROPER 44 | 45 | 46 | NONBONDED nbxmod 5 atom vatom cdiel vdistance switch vswitch - 47 | cutnb 16.0 ctofnb 12.0 ctonnb 10.0 eps 1.0 e14fac 1.0 wmin 1.5 48 | 49 | ! SWM4 50 | HDW 0.0 -0.0000 0.0000 ! SWM4-NDP water, GL, 2005, also for SWM6-NDP 51 | ODW 0.0 -0.21094325 1.78692899 ! SWM4, SWM4-NDP water, GL, 2005 52 | DRUD 0.0 -0.0000 0.0000 ! Drudes 53 | DOH2 0.0 -0.0000 0.0000 ! water Drude 54 | LPDW 0.0 -0.0000 0.0000 ! Lone pairs on water: Note overlap of SWM4 and SWM6 LPs 55 | 56 | END 57 | RETURN 58 | -------------------------------------------------------------------------------- /examples/parameters/swm6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/parameters/tip3p.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/water_dimer/mpidwater.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | -------------------------------------------------------------------------------- /examples/water_dimer/run_water_dimer.py: -------------------------------------------------------------------------------- 1 | from openmm.app import * 2 | from openmm import * 3 | from openmm.unit import * 4 | import openmm.app.element as elem 5 | from sys import stdout, argv 6 | import mpidplugin 7 | import numpy as np 8 | 9 | rvals = np.arange(1.0, 6.0, 0.1) 10 | rvals = np.arange(6.0, 1.0, -0.1) 11 | 12 | pdb = PDBFile('waterdimer.pdb') 13 | pdb = PDBFile('waterdimer_aligned.pdb') 14 | 15 | forcefield = ForceField('charmm_polar_2019.xml') 16 | modeller = Modeller(pdb.topology, pdb.positions) 17 | modeller.addExtraParticles(forcefield) 18 | system = forcefield.createSystem(modeller.topology, nonbondedMethod=LJPME, nonbondedCutoff=8*angstrom, constraints=HBonds) 19 | integrator = DrudeSCFIntegrator(1e-10*femtoseconds) 20 | integrator.setMinimizationErrorTolerance(1e-12) 21 | 22 | try: 23 | myplatform = Platform.getPlatformByName('CUDA') 24 | # Figure out which GPU to run on, i.e. did the user tell us? 25 | deviceid = argv[1] if len(argv) > 1 else '0' 26 | myproperties = {'DeviceIndex': deviceid, 'Precision': 'mixed'} 27 | myproperties = {'DeviceIndex': deviceid, 'Precision': 'double'} 28 | except: 29 | print("CUDA NOT FOUND!!!!!!!!!!") 30 | myplatform = None 31 | deviceid = "N/A" 32 | 33 | if myplatform: 34 | simulation = Simulation(modeller.topology, system, integrator, myplatform, myproperties) 35 | else: 36 | simulation = Simulation(modeller.topology, system, integrator) 37 | 38 | context = simulation.context 39 | if pdb.topology.getPeriodicBoxVectors(): 40 | context.setPeriodicBoxVectors(*pdb.topology.getPeriodicBoxVectors()) 41 | 42 | print("Running on ", context.getPlatform().getName(), " Device ID:", deviceid) 43 | 44 | context.setPositions(modeller.positions) 45 | drude = [] 46 | for r in rvals: 47 | new_coords = [] 48 | for n,c in enumerate(modeller.positions): 49 | c = c.value_in_unit(angstrom) 50 | if n > 4: 51 | c = Vec3(c[0], c[1], c[2]+r) 52 | new_coords.append(c) 53 | new_coords = new_coords*angstrom 54 | context.setPositions(new_coords) 55 | integrator.step(1) 56 | state = context.getState(getEnergy=True, getPositions=True) 57 | drude.append(state.getPotentialEnergy().value_in_unit(kilocalories_per_mole)) 58 | # 59 | #MPID 60 | # 61 | forcefield = ForceField('mpidwater.xml') 62 | system = forcefield.createSystem(pdb.topology, nonbondedMethod=LJPME, nonbondedCutoff=8*angstrom, constraints=HBonds, defaultTholeWidth=8) 63 | integrator = VerletIntegrator(1e-10*femtoseconds) 64 | if myplatform: 65 | simulation = Simulation(pdb.topology, system, integrator, myplatform, myproperties) 66 | else: 67 | simulation = Simulation(pdb.topology, system, integrator) 68 | context = simulation.context 69 | context.setPositions(pdb.positions) 70 | mpid = [] 71 | for r in rvals: 72 | new_coords = [] 73 | for n,c in enumerate(pdb.positions): 74 | c = c.value_in_unit(angstrom) 75 | if n > 2: 76 | c = Vec3(c[0], c[1], c[2]+r) 77 | new_coords.append(c) 78 | new_coords = new_coords*angstrom 79 | context.setPositions(new_coords) 80 | integrator.step(1) 81 | state = context.getState(getEnergy=True, getPositions=True) 82 | mpid.append(state.getPotentialEnergy().value_in_unit(kilocalories_per_mole)) 83 | 84 | for n,r in enumerate(rvals): 85 | print(f'{r:.2f}, {drude[n]:8.3f}, {mpid[n]:8.3f}') 86 | -------------------------------------------------------------------------------- /examples/water_dimer/waterdimer.pdb: -------------------------------------------------------------------------------- 1 | REMARK 1 CREATED WITH OPENMM 7.3, 2018-09-26 2 | CRYST1 20.000 20.000 20.000 90.00 90.00 90.00 P 1 1 3 | MODEL 1 4 | HETATM 1 O HOH A 1 0. 0.000 0. 1.00 0.00 O 5 | HETATM 2 H1 HOH A 1 -0.757 0.000 -0.586 1.00 0.00 H 6 | HETATM 3 H2 HOH A 1 0.757 0.000 -0.586 1.00 0.00 H 7 | HETATM 4 O HOH A 2 0. 0.000 0. 1.00 0.00 O 8 | HETATM 5 H1 HOH A 2 -0.757 0.000 0.586 1.00 0.00 H 9 | HETATM 6 H2 HOH A 2 0.757 0.000 0.586 1.00 0.00 H 10 | TER 7 HOH A 3 11 | ENDMDL 12 | END 13 | -------------------------------------------------------------------------------- /examples/water_dimer/waterdimer_aligned.pdb: -------------------------------------------------------------------------------- 1 | REMARK 1 CREATED WITH OPENMM 7.3, 2018-09-26 2 | CRYST1 20.000 20.000 20.000 90.00 90.00 90.00 P 1 1 3 | MODEL 1 4 | HETATM 1 O HOH A 1 0. 0.000 0. 1.00 0.00 O 5 | HETATM 2 H1 HOH A 1 -0.757 0.000 -0.586 1.00 0.00 H 6 | HETATM 3 H2 HOH A 1 0.757 0.000 -0.586 1.00 0.00 H 7 | HETATM 4 O HOH A 2 0. 0.000 0. 1.00 0.00 O 8 | HETATM 5 H1 HOH A 2 -0.757 0.000 -0.586 1.00 0.00 H 9 | HETATM 6 H2 HOH A 2 0.757 0.000 -0.586 1.00 0.00 H 10 | TER 7 HOH A 3 11 | ENDMDL 12 | END 13 | -------------------------------------------------------------------------------- /examples/waterbox/run.py: -------------------------------------------------------------------------------- 1 | from openmm.app import * 2 | from openmm import * 3 | from openmm.unit import * 4 | import openmm.app.element as elem 5 | import openmm.app.forcefield as forcefield 6 | from sys import stdout, argv 7 | import mpidplugin 8 | import numpy as np 9 | 10 | pdb = PDBFile('waterbox_31ang.pdb') 11 | 12 | #forcefield = ForceField('../parameters/tip3p.xml') 13 | #forcefield = ForceField('../parameters/swm4.xml') 14 | forcefield = ForceField('../parameters/swm6.xml') 15 | system = forcefield.createSystem(pdb.topology, nonbondedMethod=LJPME, nonbondedCutoff=8*angstrom, constraints=HBonds, 16 | defaultTholeWidth=8) 17 | integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 2*femtoseconds) 18 | system.addForce(MonteCarloBarostat(1*atmosphere, 300*kelvin, 25)) 19 | 20 | # Make sure all the forces we expect are present 21 | for force in range(system.getNumForces()): 22 | print(system.getForce(force)) 23 | 24 | try: 25 | myplatform = Platform.getPlatformByName('CUDA') 26 | # Figure out which GPU to run on, i.e. did the user tell us? 27 | deviceid = argv[1] if len(argv) > 1 else '0' 28 | myproperties = {'DeviceIndex': deviceid, 'Precision': 'mixed'} 29 | except: 30 | print("CUDA NOT FOUND!!!!!!!!!!") 31 | myplatform = None 32 | deviceid = "N/A" 33 | 34 | if myplatform: 35 | simulation = Simulation(pdb.topology, system, integrator, myplatform, myproperties) 36 | else: 37 | simulation = Simulation(pdb.topology, system, integrator) 38 | 39 | context = simulation.context 40 | if pdb.topology.getPeriodicBoxVectors(): 41 | context.setPeriodicBoxVectors(*pdb.topology.getPeriodicBoxVectors()) 42 | 43 | if os.path.isfile('restart.xml'): 44 | simulation.loadState('restart.xml') 45 | 46 | print("Running on ", context.getPlatform().getName(), " Device ID:", deviceid) 47 | 48 | # Initialize 49 | context.setPositions(pdb.positions) 50 | 51 | nsteps = 50000 52 | 53 | # Dump trajectory info every 10ps 54 | #simulation.reporters.append(DCDReporter('output.dcd', 5000)) 55 | # Dump simulation info every 1ps 56 | simulation.reporters.append(StateDataReporter(stdout, 500, progress=True, totalSteps=nsteps, 57 | step=True, potentialEnergy=True, totalEnergy=True, temperature=True, density=True, speed=True)) 58 | simulation.step(nsteps) 59 | 60 | simulation.saveState('restart.xml') 61 | -------------------------------------------------------------------------------- /openmmapi/include/OpenMMMPID.h: -------------------------------------------------------------------------------- 1 | #ifndef MPID_OPENMM_H_ 2 | #define MPID_OPENMM_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2009 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * Permission is hereby granted, free of charge, to any person obtaining a * 17 | * copy of this software and associated documentation files (the "Software"), * 18 | * to deal in the Software without restriction, including without limitation * 19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 20 | * and/or sell copies of the Software, and to permit persons to whom the * 21 | * Software is furnished to do so, subject to the following conditions: * 22 | * * 23 | * The above copyright notice and this permission notice shall be included in * 24 | * all copies or substantial portions of the Software. * 25 | * * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 28 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 29 | * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 30 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 31 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 32 | * USE OR OTHER DEALINGS IN THE SOFTWARE. * 33 | * -------------------------------------------------------------------------- */ 34 | 35 | #include "openmm/MPIDForce.h" 36 | 37 | #endif /*MPID_OPENMM_H_*/ 38 | -------------------------------------------------------------------------------- /openmmapi/include/openmm/internal/MPIDForceImpl.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENMM_MPID_MULTIPOLE_FORCE_IMPL_H_ 2 | #define OPENMM_MPID_MULTIPOLE_FORCE_IMPL_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2008 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * Permission is hereby granted, free of charge, to any person obtaining a * 17 | * copy of this software and associated documentation files (the "Software"), * 18 | * to deal in the Software without restriction, including without limitation * 19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 20 | * and/or sell copies of the Software, and to permit persons to whom the * 21 | * Software is furnished to do so, subject to the following conditions: * 22 | * * 23 | * The above copyright notice and this permission notice shall be included in * 24 | * all copies or substantial portions of the Software. * 25 | * * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 28 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 29 | * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 30 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 31 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 32 | * USE OR OTHER DEALINGS IN THE SOFTWARE. * 33 | * -------------------------------------------------------------------------- */ 34 | 35 | #include "openmm/internal/ForceImpl.h" 36 | #include "openmm/MPIDForce.h" 37 | #include "openmm/Kernel.h" 38 | #include "openmm/Vec3.h" 39 | #include 40 | #include 41 | 42 | namespace OpenMM { 43 | 44 | /** 45 | * This is the internal implementation of MPIDForce. 46 | */ 47 | 48 | class OPENMM_EXPORT_MPID MPIDForceImpl : public ForceImpl { 49 | public: 50 | MPIDForceImpl(const MPIDForce& owner); 51 | ~MPIDForceImpl(); 52 | void initialize(ContextImpl& context); 53 | const MPIDForce& getOwner() const { 54 | return owner; 55 | } 56 | void updateContextState(ContextImpl& context, bool& forcesInvalid) { 57 | // This force field doesn't update the state directly. 58 | } 59 | double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups); 60 | std::map getDefaultParameters() { 61 | return std::map(); // This force field doesn't define any parameters. 62 | } 63 | std::vector getKernelNames(); 64 | 65 | /** 66 | * Get the CovalentMap for an atom 67 | * 68 | * @param force MPIDForce force reference 69 | * @param index the index of the atom for which to set parameters 70 | * @param minCovalentIndex minimum covalent index 71 | * @param maxCovalentIndex maximum covalent index 72 | */ 73 | static void getCovalentRange(const MPIDForce& force, int index, 74 | const std::vector< MPIDForce::CovalentType>& lists, 75 | int* minCovalentIndex, int* maxCovalentIndex); 76 | 77 | /** 78 | * Get the covalent degree for the CovalentEnd lists 79 | * 80 | * @param force MPIDForce force reference 81 | * @param covalentDegree covalent degrees for the CovalentEnd lists 82 | */ 83 | static void getCovalentDegree(const MPIDForce& force, std::vector& covalentDegree); 84 | void getLabFramePermanentDipoles(ContextImpl& context, std::vector& dipoles); 85 | void getInducedDipoles(ContextImpl& context, std::vector& dipoles); 86 | void getTotalDipoles(ContextImpl& context, std::vector& dipoles); 87 | 88 | void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, 89 | std::vector< double >& outputElectrostaticPotential); 90 | 91 | void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments); 92 | void updateParametersInContext(ContextImpl& context); 93 | void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; 94 | 95 | 96 | private: 97 | const MPIDForce& owner; 98 | Kernel kernel; 99 | 100 | static int CovalentDegrees[MPIDForce::CovalentEnd]; 101 | static bool initializedCovalentDegrees; 102 | static const int* getCovalentDegrees(); 103 | }; 104 | 105 | } // namespace OpenMM 106 | 107 | #endif /*OPENMM_MPID_MULTIPOLE_FORCE_IMPL_H_*/ 108 | -------------------------------------------------------------------------------- /openmmapi/include/openmm/internal/windowsExportMPID.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENMM_WINDOWSEXPORTMPID_H_ 2 | #define OPENMM_WINDOWSEXPORTMPID_H_ 3 | 4 | /* 5 | * Shared libraries are messy in Visual Studio. We have to distinguish three 6 | * cases: 7 | * (1) this header is being used to build the OpenMM shared library 8 | * (dllexport) 9 | * (2) this header is being used by a *client* of the OpenMM shared 10 | * library (dllimport) 11 | * (3) we are building the OpenMM static library, or the client is 12 | * being compiled with the expectation of linking with the 13 | * OpenMM static library (nothing special needed) 14 | * In the CMake script for building this library, we define one of the symbols 15 | * OPENMM_MPID_BUILDING_{SHARED|STATIC}_LIBRARY 16 | * Client code normally has no special symbol defined, in which case we'll 17 | * assume it wants to use the shared library. However, if the client defines 18 | * the symbol OPENMM_USE_STATIC_LIBRARIES we'll suppress the dllimport so 19 | * that the client code can be linked with static libraries. Note that 20 | * the client symbol is not library dependent, while the library symbols 21 | * affect only the OpenMM library, meaning that other libraries can 22 | * be clients of this one. However, we are assuming all-static or all-shared. 23 | */ 24 | 25 | #ifdef _MSC_VER 26 | // We don't want to hear about how sprintf is "unsafe". 27 | #pragma warning(disable:4996) 28 | // Keep MS VC++ quiet about lack of dll export of private members. 29 | #pragma warning(disable:4251) 30 | #if defined(OPENMM_MPID_BUILDING_SHARED_LIBRARY) 31 | #define OPENMM_EXPORT_MPID __declspec(dllexport) 32 | #elif defined(OPENMM_MPID_BUILDING_STATIC_LIBRARY) || defined(OPENMM_MPID_USE_STATIC_LIBRARIES) 33 | #define OPENMM_EXPORT_MPID 34 | #else 35 | #define OPENMM_EXPORT_MPID __declspec(dllimport) // i.e., a client of a shared library 36 | #endif 37 | #else 38 | #define OPENMM_EXPORT_MPID // Linux, Mac 39 | #endif 40 | 41 | #endif // OPENMM_WINDOWSEXPORTMPID_H_ 42 | -------------------------------------------------------------------------------- /openmmapi/include/openmm/mpidKernels.h: -------------------------------------------------------------------------------- 1 | #ifndef MPID_OPENMM_KERNELS_H_ 2 | #define MPID_OPENMM_KERNELS_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2008-2015 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * Permission is hereby granted, free of charge, to any person obtaining a * 17 | * copy of this software and associated documentation files (the "Software"), * 18 | * to deal in the Software without restriction, including without limitation * 19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 20 | * and/or sell copies of the Software, and to permit persons to whom the * 21 | * Software is furnished to do so, subject to the following conditions: * 22 | * * 23 | * The above copyright notice and this permission notice shall be included in * 24 | * all copies or substantial portions of the Software. * 25 | * * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 28 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 29 | * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 30 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 31 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 32 | * USE OR OTHER DEALINGS IN THE SOFTWARE. * 33 | * -------------------------------------------------------------------------- */ 34 | 35 | #include "OpenMMMPID.h" 36 | #include "openmm/KernelImpl.h" 37 | #include "openmm/System.h" 38 | #include "openmm/Platform.h" 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | namespace OpenMM { 45 | 46 | 47 | /** 48 | * This kernel is invoked by MPIDForce to calculate the forces acting on the system and the energy of the system. 49 | */ 50 | class CalcMPIDForceKernel : public KernelImpl { 51 | 52 | public: 53 | 54 | static std::string Name() { 55 | return "CalcMPIDForce"; 56 | } 57 | 58 | CalcMPIDForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) { 59 | } 60 | 61 | /** 62 | * Initialize the kernel. 63 | * 64 | * @param system the System this kernel will be applied to 65 | * @param force the Force this kernel will be used for 66 | */ 67 | virtual void initialize(const System& system, const MPIDForce& force) = 0; 68 | 69 | /** 70 | * Execute the kernel to calculate the forces and/or energy. 71 | * 72 | * @param context the context in which to execute this kernel 73 | * @param includeForces true if forces should be calculated 74 | * @param includeEnergy true if the energy should be calculated 75 | * @return the potential energy due to the force 76 | */ 77 | virtual double execute(ContextImpl& context, bool includeForces, bool includeEnergy) = 0; 78 | 79 | virtual void getLabFramePermanentDipoles(ContextImpl& context, std::vector& dipoles) = 0; 80 | virtual void getInducedDipoles(ContextImpl& context, std::vector& dipoles) = 0; 81 | virtual void getTotalDipoles(ContextImpl& context, std::vector& dipoles) = 0; 82 | 83 | virtual void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, 84 | std::vector< double >& outputElectrostaticPotential) = 0; 85 | 86 | virtual void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments) = 0; 87 | /** 88 | * Copy changed parameters over to a context. 89 | * 90 | * @param context the context to copy parameters to 91 | * @param force the MPIDForce to copy the parameters from 92 | */ 93 | virtual void copyParametersToContext(ContextImpl& context, const MPIDForce& force) = 0; 94 | 95 | /** 96 | * Get the parameters being used for PME. 97 | * 98 | * @param alpha the separation parameter 99 | * @param nx the number of grid points along the X axis 100 | * @param ny the number of grid points along the Y axis 101 | * @param nz the number of grid points along the Z axis 102 | */ 103 | virtual void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const = 0; 104 | }; 105 | 106 | 107 | } // namespace OpenMM 108 | 109 | #endif /*MPID_OPENMM_KERNELS_H*/ 110 | -------------------------------------------------------------------------------- /platforms/cuda/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------- 2 | # OpenMM MPID Plugin CUDA Platform 3 | #---------------------------------------------------- 4 | 5 | # Collect up information about the version of the OpenMM library we're building 6 | # and make it available to the code so it can be built into the binaries. 7 | 8 | SET(MPID_CUDA_LIBRARY_NAME MPIDPluginCUDA) 9 | 10 | SET(SHARED_TARGET ${MPID_CUDA_LIBRARY_NAME}) 11 | 12 | INCLUDE_DIRECTORIES("${OPENMM_DIR}/include/openmm/cuda") 13 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/src/SimTKReference) 14 | 15 | # These are all the places to search for header files which are 16 | # to be part of the API. 17 | SET(API_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/include/internal") 18 | 19 | # Locate header files. 20 | SET(API_INCLUDE_FILES) 21 | FOREACH(dir ${API_INCLUDE_DIRS}) 22 | FILE(GLOB fullpaths ${dir}/*.h) 23 | SET(API_INCLUDE_FILES ${API_INCLUDE_FILES} ${fullpaths}) 24 | ENDFOREACH(dir) 25 | 26 | # collect up source files 27 | SET(SOURCE_FILES) # empty 28 | SET(SOURCE_INCLUDE_FILES) 29 | 30 | FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c) 31 | FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) 32 | SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append 33 | SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) 34 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include) 35 | 36 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src) 37 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/cuda/include) 38 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/cuda/src) 39 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_BINARY_DIR}/platforms/cuda/src) 40 | 41 | # Set variables needed for encoding kernel sources into a C++ class 42 | 43 | SET(CUDA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) 44 | SET(CUDA_SOURCE_CLASS CudaMPIDKernelSources) 45 | SET(CUDA_KERNELS_CPP ${CMAKE_CURRENT_BINARY_DIR}/src/${CUDA_SOURCE_CLASS}.cpp) 46 | SET(CUDA_KERNELS_H ${CMAKE_CURRENT_BINARY_DIR}/src/${CUDA_SOURCE_CLASS}.h) 47 | SET(SOURCE_FILES ${SOURCE_FILES} ${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H}) 48 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src) 49 | 50 | # Create the library 51 | 52 | INCLUDE_DIRECTORIES(${CUDA_TOOLKIT_INCLUDE}) 53 | 54 | FILE(GLOB CUDA_KERNELS ${CUDA_SOURCE_DIR}/kernels/*.cu) 55 | ADD_CUSTOM_COMMAND(OUTPUT ${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} 56 | COMMAND ${CMAKE_COMMAND} 57 | ARGS -D CUDA_SOURCE_DIR=${CUDA_SOURCE_DIR} -D CUDA_KERNELS_CPP=${CUDA_KERNELS_CPP} -D CUDA_KERNELS_H=${CUDA_KERNELS_H} -D CUDA_SOURCE_CLASS=${CUDA_SOURCE_CLASS} -P ${CMAKE_SOURCE_DIR}/platforms/cuda/EncodeCUDAFiles.cmake 58 | DEPENDS ${CUDA_KERNELS} 59 | ) 60 | SET_SOURCE_FILES_PROPERTIES(${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} PROPERTIES GENERATED TRUE) 61 | ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_INCLUDE_FILES}) 62 | 63 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${CUDA_LIBRARIES}) 64 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} OpenMM) 65 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} OpenMMCUDA) 66 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${MPID_LIBRARY_NAME}) 67 | SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES 68 | COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY ${EXTRA_COMPILE_FLAGS}" 69 | LINK_FLAGS "${EXTRA_COMPILE_FLAGS}") 70 | IF (APPLE) 71 | SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "-F/Library/Frameworks -framework CUDA ${EXTRA_COMPILE_FLAGS}") 72 | ENDIF (APPLE) 73 | 74 | INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) 75 | # Ensure that links to the main CUDA library will be resolved. 76 | IF (APPLE) 77 | SET(CUDA_LIBRARY libOpenMMCUDA.dylib) 78 | INSTALL(CODE "EXECUTE_PROCESS(COMMAND install_name_tool -change ${CUDA_LIBRARY} @loader_path/${CUDA_LIBRARY} ${CMAKE_INSTALL_PREFIX}/lib/plugins/lib${SHARED_TARGET}.dylib)") 79 | ENDIF (APPLE) 80 | 81 | SUBDIRS (tests) 82 | -------------------------------------------------------------------------------- /platforms/cuda/EncodeCUDAFiles.cmake: -------------------------------------------------------------------------------- 1 | FILE(GLOB CUDA_KERNELS ${CUDA_SOURCE_DIR}/kernels/*.cu) 2 | SET(CUDA_FILE_DECLARATIONS) 3 | SET(CUDA_FILE_DEFINITIONS) 4 | CONFIGURE_FILE(${CUDA_SOURCE_DIR}/${CUDA_SOURCE_CLASS}.cpp.in ${CUDA_KERNELS_CPP}) 5 | FOREACH(file ${CUDA_KERNELS}) 6 | # Load the file contents and process it. 7 | FILE(STRINGS ${file} file_content NEWLINE_CONSUME) 8 | # Replace all backslashes by double backslashes as they are being put in a C string. 9 | # Be careful not to replace the backslash before a semicolon as that is the CMAKE 10 | # internal escaping of a semicolon to prevent it from acting as a list seperator. 11 | STRING(REGEX REPLACE "\\\\([^;])" "\\\\\\\\\\1" file_content "${file_content}") 12 | # Escape double quotes as being put in a C string. 13 | STRING(REPLACE "\"" "\\\"" file_content "${file_content}") 14 | # Split in separate C strings for each line. 15 | STRING(REPLACE "\n" "\\n\"\n\"" file_content "${file_content}") 16 | 17 | # Determine a name for the variable that will contain this file's contents 18 | FILE(RELATIVE_PATH filename ${CUDA_SOURCE_DIR}/kernels ${file}) 19 | STRING(LENGTH ${filename} filename_length) 20 | MATH(EXPR filename_length ${filename_length}-3) 21 | STRING(SUBSTRING ${filename} 0 ${filename_length} variable_name) 22 | 23 | # Record the variable declaration and definition. 24 | SET(CUDA_FILE_DECLARATIONS ${CUDA_FILE_DECLARATIONS}static\ const\ std::string\ ${variable_name};\n) 25 | FILE(APPEND ${CUDA_KERNELS_CPP} const\ string\ ${CUDA_SOURCE_CLASS}::${variable_name}\ =\ \"${file_content}\"\;\n) 26 | ENDFOREACH(file) 27 | CONFIGURE_FILE(${CUDA_SOURCE_DIR}/${CUDA_SOURCE_CLASS}.h.in ${CUDA_KERNELS_H}) 28 | -------------------------------------------------------------------------------- /platforms/cuda/include/MPIDCudaKernelFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef MPID_OPENMM_CUDAKERNELFACTORY_H_ 2 | #define MPID_OPENMM_CUDAKERNELFACTORY_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2008 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * This program is free software: you can redistribute it and/or modify * 17 | * it under the terms of the GNU Lesser General Public License as published * 18 | * by the Free Software Foundation, either version 3 of the License, or * 19 | * (at your option) any later version. * 20 | * * 21 | * This program is distributed in the hope that it will be useful, * 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 24 | * GNU Lesser General Public License for more details. * 25 | * * 26 | * You should have received a copy of the GNU Lesser General Public License * 27 | * along with this program. If not, see . * 28 | * -------------------------------------------------------------------------- */ 29 | 30 | #include "openmm/KernelFactory.h" 31 | 32 | namespace OpenMM { 33 | 34 | /** 35 | * This KernelFactory creates all kernels for MPIDCudaPlatform. 36 | */ 37 | 38 | class MPIDCudaKernelFactory : public KernelFactory { 39 | public: 40 | KernelImpl* createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const; 41 | }; 42 | 43 | } // namespace OpenMM 44 | 45 | #endif /*MPID_OPENMM_CUDAKERNELFACTORY_H_*/ 46 | -------------------------------------------------------------------------------- /platforms/cuda/src/CudaMPIDKernelSources.cpp.in: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- * 2 | * OpenMM * 3 | * -------------------------------------------------------------------------- * 4 | * This is part of the OpenMM molecular simulation toolkit originating from * 5 | * Simbios, the NIH National Center for Physics-Based Simulation of * 6 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 7 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 8 | * * 9 | * Portions copyright (c) 2012 Stanford University and the Authors. * 10 | * Authors: Peter Eastman * 11 | * Contributors: * 12 | * * 13 | * This program is free software: you can redistribute it and/or modify * 14 | * it under the terms of the GNU Lesser General Public License as published * 15 | * by the Free Software Foundation, either version 3 of the License, or * 16 | * (at your option) any later version. * 17 | * * 18 | * This program is distributed in the hope that it will be useful, * 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 21 | * GNU Lesser General Public License for more details. * 22 | * * 23 | * You should have received a copy of the GNU Lesser General Public License * 24 | * along with this program. If not, see . * 25 | * -------------------------------------------------------------------------- */ 26 | 27 | #include "CudaMPIDKernelSources.h" 28 | 29 | using namespace OpenMM; 30 | using namespace std; 31 | 32 | -------------------------------------------------------------------------------- /platforms/cuda/src/CudaMPIDKernelSources.h.in: -------------------------------------------------------------------------------- 1 | #ifndef OPENMM_CUDAMPIDKERNELSOURCES_H_ 2 | #define OPENMM_CUDAMPIDKERNELSOURCES_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMM * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2010-2012 Stanford University and the Authors. * 13 | * Authors: Peter Eastman * 14 | * Contributors: * 15 | * * 16 | * This program is free software: you can redistribute it and/or modify * 17 | * it under the terms of the GNU Lesser General Public License as published * 18 | * by the Free Software Foundation, either version 3 of the License, or * 19 | * (at your option) any later version. * 20 | * * 21 | * This program is distributed in the hope that it will be useful, * 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 24 | * GNU Lesser General Public License for more details. * 25 | * * 26 | * You should have received a copy of the GNU Lesser General Public License * 27 | * along with this program. If not, see . * 28 | * -------------------------------------------------------------------------- */ 29 | 30 | #include "openmm/internal/windowsExport.h" 31 | #include 32 | 33 | namespace OpenMM { 34 | 35 | /** 36 | * This class is a central holding place for the source code of CUDA kernels. 37 | * The CMake build script inserts declarations into it based on the .cu files in the 38 | * kernels subfolder. 39 | */ 40 | 41 | class OPENMM_EXPORT CudaMPIDKernelSources { 42 | public: 43 | @CUDA_FILE_DECLARATIONS@ 44 | }; 45 | 46 | } // namespace OpenMM 47 | 48 | #endif /*OPENMM_CUDAMPIDKERNELSOURCES_H_*/ 49 | -------------------------------------------------------------------------------- /platforms/cuda/src/MPIDCudaKernelFactory.cpp: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- * 2 | * OpenMMMPID * 3 | * -------------------------------------------------------------------------- * 4 | * This is part of the OpenMM molecular simulation toolkit originating from * 5 | * Simbios, the NIH National Center for Physics-Based Simulation of * 6 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 7 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 8 | * * 9 | * Portions copyright (c) 2008-2016 Stanford University and the Authors. * 10 | * Authors: Mark Friedrichs, Peter Eastman * 11 | * Contributors: * 12 | * * 13 | * This program is free software: you can redistribute it and/or modify * 14 | * it under the terms of the GNU Lesser General Public License as published * 15 | * by the Free Software Foundation, either version 3 of the License, or * 16 | * (at your option) any later version. * 17 | * * 18 | * This program is distributed in the hope that it will be useful, * 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 21 | * GNU Lesser General Public License for more details. * 22 | * * 23 | * You should have received a copy of the GNU Lesser General Public License * 24 | * along with this program. If not, see . * 25 | * -------------------------------------------------------------------------- */ 26 | 27 | #include "MPIDCudaKernelFactory.h" 28 | #include "MPIDCudaKernels.h" 29 | #include "CudaPlatform.h" 30 | #include "openmm/internal/ContextImpl.h" 31 | #include "openmm/OpenMMException.h" 32 | #include "openmm/internal/windowsExport.h" 33 | 34 | using namespace OpenMM; 35 | 36 | #ifdef OPENMM_BUILDING_STATIC_LIBRARY 37 | static void registerPlatforms() { 38 | #else 39 | extern "C" OPENMM_EXPORT void registerPlatforms() { 40 | #endif 41 | } 42 | 43 | #ifdef OPENMM_BUILDING_STATIC_LIBRARY 44 | static void registerKernelFactories() { 45 | #else 46 | extern "C" OPENMM_EXPORT void registerKernelFactories() { 47 | #endif 48 | try { 49 | Platform& platform = Platform::getPlatformByName("CUDA"); 50 | MPIDCudaKernelFactory* factory = new MPIDCudaKernelFactory(); 51 | platform.registerKernelFactory(CalcMPIDForceKernel::Name(), factory); 52 | } 53 | catch (...) { 54 | // Ignore. The CUDA platform isn't available. 55 | } 56 | } 57 | 58 | extern "C" OPENMM_EXPORT void registerMPIDCudaKernelFactories() { 59 | try { 60 | Platform::getPlatformByName("CUDA"); 61 | } 62 | catch (...) { 63 | Platform::registerPlatform(new CudaPlatform()); 64 | } 65 | registerKernelFactories(); 66 | } 67 | 68 | KernelImpl* MPIDCudaKernelFactory::createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const { 69 | CudaPlatform::PlatformData& data = *static_cast(context.getPlatformData()); 70 | CudaContext& cu = *data.contexts[0]; 71 | 72 | if (name == CalcMPIDForceKernel::Name()) 73 | return new CudaCalcMPIDForceKernel(name, platform, cu, context.getSystem()); 74 | 75 | throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str()); 76 | } 77 | -------------------------------------------------------------------------------- /platforms/cuda/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Testing 3 | # 4 | 5 | ENABLE_TESTING() 6 | 7 | INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIR}) 8 | 9 | # Automatically create tests using files named "Test*.cpp" 10 | FILE(GLOB TEST_PROGS "*Test*.cpp") 11 | FOREACH(TEST_PROG ${TEST_PROGS}) 12 | GET_FILENAME_COMPONENT(TEST_ROOT ${TEST_PROG} NAME_WE) 13 | 14 | # Link with shared library 15 | ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG}) 16 | TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_MPID_TARGET} ${SHARED_TARGET}) 17 | IF (APPLE) 18 | SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") 19 | ELSE (APPLE) 20 | SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") 21 | ENDIF (APPLE) 22 | ADD_TEST(${TEST_ROOT}Single ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} single) 23 | ADD_TEST(${TEST_ROOT}Mixed ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} mixed) 24 | ADD_TEST(${TEST_ROOT}Double ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT} double) 25 | 26 | ENDFOREACH(TEST_PROG ${TEST_PROGS}) 27 | -------------------------------------------------------------------------------- /platforms/reference/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------- 2 | # OpenMM Reference MPID Implementation 3 | # 4 | # Creates OpenMMMPIDReference library. 5 | # 6 | # Windows: 7 | # OpenMMMPIDReference.dll 8 | # OpenMMMPIDReference.lib 9 | # Unix: 10 | # libOpenMMMPIDReference.so 11 | #---------------------------------------------------- 12 | 13 | # The source is organized into subdirectories, but we handle them all from 14 | # this CMakeLists file rather than letting CMake visit them as SUBDIRS. 15 | SET(OPENMM_SOURCE_SUBDIRS .) 16 | 17 | # Collect up information about the version of the OpenMM library we're building 18 | # and make it available to the code so it can be built into the binaries. 19 | 20 | SET(OPENMMMPIDREFERENCE_LIBRARY_NAME OpenMMMPIDReference) 21 | 22 | SET(SHARED_TARGET ${OPENMMMPIDREFERENCE_LIBRARY_NAME}) 23 | 24 | INCLUDE_DIRECTORIES("${OPENMM_DIR}/include/openmm/reference") 25 | INCLUDE_DIRECTORIES("${OPENMM_DIR}/libraries/jama/include") 26 | # These are all the places to search for header files which are 27 | # to be part of the API. 28 | SET(API_INCLUDE_DIRS) # start empty 29 | FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS}) 30 | # append 31 | SET(API_INCLUDE_DIRS ${API_INCLUDE_DIRS} 32 | ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include 33 | ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include/internal) 34 | ENDFOREACH(subdir) 35 | 36 | # We'll need both *relative* path names, starting with their API_INCLUDE_DIRS, 37 | # and absolute pathnames. 38 | SET(API_REL_INCLUDE_FILES) # start these out empty 39 | SET(API_ABS_INCLUDE_FILES) 40 | 41 | FOREACH(dir ${API_INCLUDE_DIRS}) 42 | FILE(GLOB fullpaths ${dir}/*.h) # returns full pathnames 43 | SET(API_ABS_INCLUDE_FILES ${API_ABS_INCLUDE_FILES} ${fullpaths}) 44 | 45 | FOREACH(pathname ${fullpaths}) 46 | GET_FILENAME_COMPONENT(filename ${pathname} NAME) 47 | SET(API_REL_INCLUDE_FILES ${API_REL_INCLUDE_FILES} ${dir}/${filename}) 48 | ENDFOREACH(pathname) 49 | ENDFOREACH(dir) 50 | 51 | # collect up source files 52 | SET(SOURCE_FILES) # empty 53 | SET(SOURCE_INCLUDE_FILES) 54 | 55 | FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS}) 56 | FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c) 57 | FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h) 58 | SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append 59 | SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) 60 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include) 61 | ENDFOREACH(subdir) 62 | 63 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src) 64 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src/SimTKReference) 65 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/include) 66 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/src) 67 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/reference/src/SimTKReference) 68 | 69 | # Create the library 70 | 71 | ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) 72 | 73 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME}) 74 | TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${SHARED_MPID_TARGET}) 75 | SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") 76 | SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}") 77 | 78 | INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) 79 | 80 | IF(BUILD_TESTING AND OPENMM_BUILD_REFERENCE_TESTS) 81 | SUBDIRS (tests) 82 | ENDIF(BUILD_TESTING AND OPENMM_BUILD_REFERENCE_TESTS) 83 | -------------------------------------------------------------------------------- /platforms/reference/include/MPIDReferenceKernelFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef MPID_OPENMM_REFERERENCE_KERNEL_FACTORY_H_ 2 | #define MPID_OPENMM_REFERERENCE_KERNEL_FACTORY_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2008 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * This program is free software: you can redistribute it and/or modify * 17 | * it under the terms of the GNU Lesser General Public License as published * 18 | * by the Free Software Foundation, either version 3 of the License, or * 19 | * (at your option) any later version. * 20 | * * 21 | * This program is distributed in the hope that it will be useful, * 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 24 | * GNU Lesser General Public License for more details. * 25 | * * 26 | * You should have received a copy of the GNU Lesser General Public License * 27 | * along with this program. If not, see . * 28 | * -------------------------------------------------------------------------- */ 29 | 30 | #include "openmm/KernelFactory.h" 31 | 32 | namespace OpenMM { 33 | 34 | /** 35 | * This KernelFactory creates all kernels for MPIDReferencePlatform. 36 | */ 37 | 38 | class MPIDReferenceKernelFactory : public KernelFactory { 39 | public: 40 | KernelImpl* createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const; 41 | }; 42 | 43 | } // namespace OpenMM 44 | 45 | #endif /*MPID_OPENMM_REFERERENCE_KERNEL_FACTORY_H_*/ 46 | -------------------------------------------------------------------------------- /platforms/reference/include/windowsExportAmoebaReference.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENMM_WINDOWS_EXPORT_REFERENCE_H_ 2 | #define OPENMM_WINDOWS_EXPORT_REFERENCE_H_ 3 | 4 | /* 5 | * Shared libraries are messy in Visual Studio. We have to distinguish three 6 | * cases: 7 | * (1) this header is being used to build the OpenMM shared library 8 | * (dllexport) 9 | * (2) this header is being used by a *client* of the OpenMM shared 10 | * library (dllimport) 11 | * (3) we are building the OpenMM static library, or the client is 12 | * being compiled with the expectation of linking with the 13 | * OpenMM static library (nothing special needed) 14 | * In the CMake script for building this library, we define one of the symbols 15 | * OpenMMCUDA_BUILDING_{SHARED|STATIC}_LIBRARY 16 | * Client code normally has no special symbol defined, in which case we'll 17 | * assume it wants to use the shared library. However, if the client defines 18 | * the symbol OPENMM_USE_STATIC_LIBRARIES we'll suppress the dllimport so 19 | * that the client code can be linked with static libraries. Note that 20 | * the client symbol is not library dependent, while the library symbols 21 | * affect only the OpenMM library, meaning that other libraries can 22 | * be clients of this one. However, we are assuming all-static or all-shared. 23 | */ 24 | 25 | #ifdef _MSC_VER 26 | // We don't want to hear about how sprintf is "unsafe". 27 | #pragma warning(disable:4996) 28 | // Keep MS VC++ quiet about lack of dll export of private members. 29 | #pragma warning(disable:4251) 30 | #if defined(OPENMM_MPID_REFERENCE_BUILDING_SHARED_LIBRARY) 31 | #define OPENMM_MPID_REFERENCE_EXPORT __declspec(dllexport) 32 | #elif defined(OPENMM_MPID_REFERENCE_BUILDING_STATIC_LIBRARY) || defined(OPENMM_MPID_REFERENCE_USE_STATIC_LIBRARIES) 33 | #define OPENMM_MPID_REFERENCE_EXPORT 34 | #else 35 | #define OPENMM_MPID_REFERENCE_EXPORT __declspec(dllimport) // i.e., a client of a shared library 36 | #endif 37 | #else 38 | #define OPENMM_MPID_REFERENCE_EXPORT // Linux, Mac 39 | #endif 40 | 41 | #endif // OPENMM_WINDOWS_EXPORT_REFERENCE_H_ 42 | -------------------------------------------------------------------------------- /platforms/reference/src/MPIDReferenceKernelFactory.cpp: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- * 2 | * OpenMMMPID * 3 | * -------------------------------------------------------------------------- * 4 | * This is part of the OpenMM molecular simulation toolkit originating from * 5 | * Simbios, the NIH National Center for Physics-Based Simulation of * 6 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 7 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 8 | * * 9 | * Portions copyright (c) 2008-2016 Stanford University and the Authors. * 10 | * Authors: Mark Friedrichs, Peter Eastman * 11 | * Contributors: * 12 | * * 13 | * This program is free software: you can redistribute it and/or modify * 14 | * it under the terms of the GNU Lesser General Public License as published * 15 | * by the Free Software Foundation, either version 3 of the License, or * 16 | * (at your option) any later version. * 17 | * * 18 | * This program is distributed in the hope that it will be useful, * 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 21 | * GNU Lesser General Public License for more details. * 22 | * * 23 | * You should have received a copy of the GNU Lesser General Public License * 24 | * along with this program. If not, see . * 25 | * -------------------------------------------------------------------------- */ 26 | 27 | #include "MPIDReferenceKernelFactory.h" 28 | #include "MPIDReferenceKernels.h" 29 | #include "ReferencePlatform.h" 30 | #include "openmm/internal/ContextImpl.h" 31 | #include "openmm/OpenMMException.h" 32 | 33 | using namespace OpenMM; 34 | 35 | #ifdef OPENMM_BUILDING_STATIC_LIBRARY 36 | static void registerPlatforms() { 37 | #else 38 | extern "C" OPENMM_EXPORT void registerPlatforms() { 39 | #endif 40 | } 41 | 42 | #ifdef OPENMM_BUILDING_STATIC_LIBRARY 43 | static void registerKernelFactories() { 44 | #else 45 | extern "C" OPENMM_EXPORT void registerKernelFactories() { 46 | #endif 47 | for (int i = 0; i < Platform::getNumPlatforms(); i++) { 48 | Platform& platform = Platform::getPlatform(i); 49 | if (dynamic_cast(&platform) != NULL) { 50 | MPIDReferenceKernelFactory* factory = new MPIDReferenceKernelFactory(); 51 | platform.registerKernelFactory(CalcMPIDForceKernel::Name(), factory); 52 | } 53 | } 54 | } 55 | 56 | extern "C" OPENMM_EXPORT void registerMPIDReferenceKernelFactories() { 57 | registerKernelFactories(); 58 | } 59 | 60 | KernelImpl* MPIDReferenceKernelFactory::createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const { 61 | ReferencePlatform::PlatformData& referencePlatformData = *static_cast(context.getPlatformData()); 62 | 63 | // create MPIDReferenceData object if contextToMPIDDataMap does not contain 64 | // key equal to current context 65 | if (name == CalcMPIDForceKernel::Name()) 66 | return new ReferenceCalcMPIDForceKernel(name, platform, context.getSystem()); 67 | 68 | throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str()); 69 | } 70 | -------------------------------------------------------------------------------- /platforms/reference/src/MPIDReferenceKernels.h: -------------------------------------------------------------------------------- 1 | #ifndef MPID_OPENMM_REFERENCE_KERNELS_H_ 2 | #define MPID_OPENMM_REFERENCE_KERNELS_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2008-2015 Stanford University and the Authors. * 13 | * Authors: * 14 | * Contributors: * 15 | * * 16 | * This program is free software: you can redistribute it and/or modify * 17 | * it under the terms of the GNU Lesser General Public License as published * 18 | * by the Free Software Foundation, either version 3 of the License, or * 19 | * (at your option) any later version. * 20 | * * 21 | * This program is distributed in the hope that it will be useful, * 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 24 | * GNU Lesser General Public License for more details. * 25 | * * 26 | * You should have received a copy of the GNU Lesser General Public License * 27 | * along with this program. If not, see . * 28 | * -------------------------------------------------------------------------- */ 29 | 30 | #include "openmm/System.h" 31 | #include "openmm/mpidKernels.h" 32 | #include "openmm/MPIDForce.h" 33 | #include "MPIDReferenceForce.h" 34 | #include "ReferenceNeighborList.h" 35 | #include "SimTKOpenMMRealType.h" 36 | 37 | namespace OpenMM { 38 | 39 | 40 | /** 41 | * This kernel is invoked by MPIDForce to calculate the forces acting on the system and the energy of the system. 42 | */ 43 | class ReferenceCalcMPIDForceKernel : public CalcMPIDForceKernel { 44 | public: 45 | ReferenceCalcMPIDForceKernel(std::string name, const Platform& platform, const System& system); 46 | ~ReferenceCalcMPIDForceKernel(); 47 | /** 48 | * Initialize the kernel. 49 | * 50 | * @param system the System this kernel will be applied to 51 | * @param force the MPIDForce this kernel will be used for 52 | */ 53 | void initialize(const System& system, const MPIDForce& force); 54 | /** 55 | * Setup for MPIDReferenceForce instance. 56 | * 57 | * @param context the current context 58 | * 59 | * @return pointer to initialized instance of MPIDReferenceForce 60 | */ 61 | MPIDReferenceForce* setupMPIDReferenceForce(ContextImpl& context); 62 | /** 63 | * Execute the kernel to calculate the forces and/or energy. 64 | * 65 | * @param context the context in which to execute this kernel 66 | * @param includeForces true if forces should be calculated 67 | * @param includeEnergy true if the energy should be calculated 68 | * @return the potential energy due to the force 69 | */ 70 | double execute(ContextImpl& context, bool includeForces, bool includeEnergy); 71 | /** 72 | * Get the induced dipole moments of all particles. 73 | * 74 | * @param context the Context for which to get the induced dipoles 75 | * @param dipoles the induced dipole moment of particle i is stored into the i'th element 76 | */ 77 | void getInducedDipoles(ContextImpl& context, std::vector& dipoles); 78 | /** 79 | * Get the fixed dipole moments of all particles in the global reference frame. 80 | * 81 | * @param context the Context for which to get the fixed dipoles 82 | * @param dipoles the fixed dipole moment of particle i is stored into the i'th element 83 | */ 84 | void getLabFramePermanentDipoles(ContextImpl& context, std::vector& dipoles); 85 | /** 86 | * Get the total dipole moments of all particles in the global reference frame. 87 | * 88 | * @param context the Context for which to get the fixed dipoles 89 | * @param dipoles the fixed dipole moment of particle i is stored into the i'th element 90 | */ 91 | void getTotalDipoles(ContextImpl& context, std::vector& dipoles); 92 | /** 93 | * Calculate the electrostatic potential given vector of grid coordinates. 94 | * 95 | * @param context context 96 | * @param inputGrid input grid coordinates 97 | * @param outputElectrostaticPotential output potential 98 | */ 99 | void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, 100 | std::vector< double >& outputElectrostaticPotential); 101 | 102 | /** 103 | * Get the system multipole moments. 104 | * 105 | * @param context context 106 | * @param outputMultipoleMoments vector of multipole moments: 107 | (charge, 108 | dipole_x, dipole_y, dipole_z, 109 | quadrupole_xx, quadrupole_xy, quadrupole_xz, 110 | quadrupole_yx, quadrupole_yy, quadrupole_yz, 111 | quadrupole_zx, quadrupole_zy, quadrupole_zz) 112 | */ 113 | void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments); 114 | /** 115 | * Copy changed parameters over to a context. 116 | * 117 | * @param context the context to copy parameters to 118 | * @param force the MPIDForce to copy the parameters from 119 | */ 120 | void copyParametersToContext(ContextImpl& context, const MPIDForce& force); 121 | /** 122 | * Get the parameters being used for PME. 123 | * 124 | * @param alpha the separation parameter 125 | * @param nx the number of grid points along the X axis 126 | * @param ny the number of grid points along the Y axis 127 | * @param nz the number of grid points along the Z axis 128 | */ 129 | void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const; 130 | 131 | private: 132 | 133 | int numMultipoles; 134 | MPIDForce::NonbondedMethod nonbondedMethod; 135 | MPIDForce::PolarizationType polarizationType; 136 | std::vector charges; 137 | std::vector dipoles; 138 | std::vector quadrupoles; 139 | std::vector octopoles; 140 | std::vector tholes; 141 | std::vector dampingFactors; 142 | std::vector > polarity; 143 | std::vector axisTypes; 144 | std::vector multipoleAtomZs; 145 | std::vector multipoleAtomXs; 146 | std::vector multipoleAtomYs; 147 | std::vector< std::vector< std::vector > > multipoleAtomCovalentInfo; 148 | 149 | int mutualInducedMaxIterations; 150 | double mutualInducedTargetEpsilon; 151 | std::vector extrapolationCoefficients; 152 | 153 | bool usePme; 154 | double alphaEwald; 155 | double defaultTholeWidth; 156 | double scaleFactor14; 157 | double cutoffDistance; 158 | std::vector pmeGridDimension; 159 | 160 | const System& system; 161 | }; 162 | 163 | 164 | } // namespace OpenMM 165 | 166 | #endif /*MPID_OPENMM_REFERENCE_KERNELS_H*/ 167 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/jama_cholesky.h: -------------------------------------------------------------------------------- 1 | #ifndef JAMA_CHOLESKY_H 2 | #define JAMA_CHOLESKY_H 3 | 4 | #include "math.h" 5 | /* needed for sqrt() below. */ 6 | 7 | 8 | namespace JAMA 9 | { 10 | 11 | using namespace TNT; 12 | 13 | /** 14 |

15 | For a symmetric, positive definite matrix A, this function 16 | computes the Cholesky factorization, i.e. it computes a lower 17 | triangular matrix L such that A = L*L'. 18 | If the matrix is not symmetric or positive definite, the function 19 | computes only a partial decomposition. This can be tested with 20 | the is_spd() flag. 21 | 22 |

Typical usage looks like: 23 |

 24 | 	Array2D A(n,n);
 25 | 	Array2D L;
 26 | 
 27 | 	 ... 
 28 | 
 29 | 	Cholesky chol(A);
 30 | 
 31 | 	if (chol.is_spd())
 32 | 		L = chol.getL();
 33 | 		
 34 |   	else
 35 | 		cout << "factorization was not complete.\n";
 36 | 
 37 | 	
38 | 39 | 40 |

41 | (Adapted from JAMA, a Java Matrix Library, developed by jointly 42 | by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama). 43 | 44 | */ 45 | 46 | template 47 | class Cholesky 48 | { 49 | Array2D L_; // lower triangular factor 50 | int isspd; // 1 if matrix to be factored was SPD 51 | 52 | public: 53 | 54 | Cholesky(); 55 | Cholesky(const Array2D &A); 56 | Array2D getL() const; 57 | Array1D solve(const Array1D &B); 58 | Array2D solve(const Array2D &B); 59 | int is_spd() const; 60 | 61 | }; 62 | 63 | template 64 | Cholesky::Cholesky() : L_(0,0), isspd(0) {} 65 | 66 | /** 67 | @return 1, if original matrix to be factored was symmetric 68 | positive-definite (SPD). 69 | */ 70 | template 71 | int Cholesky::is_spd() const 72 | { 73 | return isspd; 74 | } 75 | 76 | /** 77 | @return the lower triangular factor, L, such that L*L'=A. 78 | */ 79 | template 80 | Array2D Cholesky::getL() const 81 | { 82 | return L_; 83 | } 84 | 85 | /** 86 | Constructs a lower triangular matrix L, such that L*L'= A. 87 | If A is not symmetric positive-definite (SPD), only a 88 | partial factorization is performed. If is_spd() 89 | evalutate true (1) then the factorizaiton was successful. 90 | */ 91 | template 92 | Cholesky::Cholesky(const Array2D &A) 93 | { 94 | 95 | 96 | int m = A.dim1(); 97 | int n = A.dim2(); 98 | 99 | isspd = (m == n); 100 | 101 | if (m != n) 102 | { 103 | L_ = Array2D(0,0); 104 | return; 105 | } 106 | 107 | L_ = Array2D(n,n); 108 | 109 | 110 | // Main loop. 111 | for (int j = 0; j < n; j++) 112 | { 113 | Real d(0.0); 114 | for (int k = 0; k < j; k++) 115 | { 116 | Real s(0.0); 117 | for (int i = 0; i < k; i++) 118 | { 119 | s += L_[k][i]*L_[j][i]; 120 | } 121 | L_[j][k] = s = (A[j][k] - s)/L_[k][k]; 122 | d = d + s*s; 123 | isspd = isspd && (A[k][j] == A[j][k]); 124 | } 125 | d = A[j][j] - d; 126 | isspd = isspd && (d > 0.0); 127 | L_[j][j] = sqrt(d > 0.0 ? d : 0.0); 128 | for (int k = j+1; k < n; k++) 129 | { 130 | L_[j][k] = 0.0; 131 | } 132 | } 133 | } 134 | 135 | /** 136 | 137 | Solve a linear system A*x = b, using the previously computed 138 | cholesky factorization of A: L*L'. 139 | 140 | @param B A Matrix with as many rows as A and any number of columns. 141 | @return x so that L*L'*x = b. If b is nonconformat, or if A 142 | was not symmetric posidtive definite, a null (0x0) 143 | array is returned. 144 | */ 145 | template 146 | Array1D Cholesky::solve(const Array1D &b) 147 | { 148 | int n = L_.dim1(); 149 | if (b.dim1() != n) 150 | return Array1D(); 151 | 152 | 153 | Array1D x = b.copy(); 154 | 155 | 156 | // Solve L*y = b; 157 | for (int k = 0; k < n; k++) 158 | { 159 | for (int i = 0; i < k; i++) 160 | x[k] -= x[i]*L_[k][i]; 161 | x[k] /= L_[k][k]; 162 | 163 | } 164 | 165 | // Solve L'*X = Y; 166 | for (int k = n-1; k >= 0; k--) 167 | { 168 | for (int i = k+1; i < n; i++) 169 | x[k] -= x[i]*L_[i][k]; 170 | x[k] /= L_[k][k]; 171 | } 172 | 173 | return x; 174 | } 175 | 176 | 177 | /** 178 | 179 | Solve a linear system A*X = B, using the previously computed 180 | cholesky factorization of A: L*L'. 181 | 182 | @param B A Matrix with as many rows as A and any number of columns. 183 | @return X so that L*L'*X = B. If B is nonconformat, or if A 184 | was not symmetric posidtive definite, a null (0x0) 185 | array is returned. 186 | */ 187 | template 188 | Array2D Cholesky::solve(const Array2D &B) 189 | { 190 | int n = L_.dim1(); 191 | if (B.dim1() != n) 192 | return Array2D(); 193 | 194 | 195 | Array2D X = B.copy(); 196 | int nx = B.dim2(); 197 | 198 | // Cleve's original code 199 | #if 0 200 | // Solve L*Y = B; 201 | for (int k = 0; k < n; k++) { 202 | for (int i = k+1; i < n; i++) { 203 | for (int j = 0; j < nx; j++) { 204 | X[i][j] -= X[k][j]*L_[k][i]; 205 | } 206 | } 207 | for (int j = 0; j < nx; j++) { 208 | X[k][j] /= L_[k][k]; 209 | } 210 | } 211 | 212 | // Solve L'*X = Y; 213 | for (int k = n-1; k >= 0; k--) { 214 | for (int j = 0; j < nx; j++) { 215 | X[k][j] /= L_[k][k]; 216 | } 217 | for (int i = 0; i < k; i++) { 218 | for (int j = 0; j < nx; j++) { 219 | X[i][j] -= X[k][j]*L_[k][i]; 220 | } 221 | } 222 | } 223 | #endif 224 | 225 | 226 | // Solve L*y = b; 227 | for (int j=0; j< nx; j++) 228 | { 229 | for (int k = 0; k < n; k++) 230 | { 231 | for (int i = 0; i < k; i++) 232 | X[k][j] -= X[i][j]*L_[k][i]; 233 | X[k][j] /= L_[k][k]; 234 | } 235 | } 236 | 237 | // Solve L'*X = Y; 238 | for (int j=0; j= 0; k--) 241 | { 242 | for (int i = k+1; i < n; i++) 243 | X[k][j] -= X[i][j]*L_[i][k]; 244 | X[k][j] /= L_[k][k]; 245 | } 246 | } 247 | 248 | 249 | 250 | return X; 251 | } 252 | 253 | 254 | } 255 | // namespace JAMA 256 | 257 | #endif 258 | // JAMA_CHOLESKY_H 259 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/jama_lu.h: -------------------------------------------------------------------------------- 1 | #ifndef JAMA_LU_H 2 | #define JAMA_LU_H 3 | 4 | #include "tnt.h" 5 | #include 6 | //for min(), max() below 7 | 8 | using namespace TNT; 9 | using namespace std; 10 | 11 | namespace JAMA 12 | { 13 | 14 | /** LU Decomposition. 15 |

16 | For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n 17 | unit lower triangular matrix L, an n-by-n upper triangular matrix U, 18 | and a permutation vector piv of length m so that A(piv,:) = L*U. 19 | If m < n, then L is m-by-m and U is m-by-n. 20 |

21 | The LU decompostion with pivoting always exists, even if the matrix is 22 | singular, so the constructor will never fail. The primary use of the 23 | LU decomposition is in the solution of square systems of simultaneous 24 | linear equations. This will fail if isNonsingular() returns false. 25 | */ 26 | template 27 | class LU 28 | { 29 | 30 | 31 | 32 | /* Array for internal storage of decomposition. */ 33 | Array2D LU_; 34 | int m, n, pivsign; 35 | Array1D piv; 36 | 37 | 38 | Array2D permute_copy(const Array2D &A, 39 | const Array1D &piv, int j0, int j1) 40 | { 41 | int piv_length = piv.dim(); 42 | 43 | Array2D X(piv_length, j1-j0+1); 44 | 45 | 46 | for (int i = 0; i < piv_length; i++) 47 | for (int j = j0; j <= j1; j++) 48 | X[i][j-j0] = A[piv[i]][j]; 49 | 50 | return X; 51 | } 52 | 53 | Array1D permute_copy(const Array1D &A, 54 | const Array1D &piv) 55 | { 56 | int piv_length = piv.dim(); 57 | if (piv_length != A.dim()) 58 | return Array1D(); 59 | 60 | Array1D x(piv_length); 61 | 62 | 63 | for (int i = 0; i < piv_length; i++) 64 | x[i] = A[piv[i]]; 65 | 66 | return x; 67 | } 68 | 69 | 70 | public : 71 | 72 | /** LU Decomposition 73 | @param A Rectangular matrix 74 | @return LU Decomposition object to access L, U and piv. 75 | */ 76 | 77 | LU (const Array2D &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()), 78 | piv(A.dim1()) 79 | 80 | { 81 | 82 | // Use a "left-looking", dot-product, Crout/Doolittle algorithm. 83 | 84 | 85 | for (int i = 0; i < m; i++) { 86 | piv[i] = i; 87 | } 88 | pivsign = 1; 89 | Real *LUrowi = 0;; 90 | Array1D LUcolj(m); 91 | 92 | // Outer loop. 93 | 94 | for (int j = 0; j < n; j++) { 95 | 96 | // Make a copy of the j-th column to localize references. 97 | 98 | for (int i = 0; i < m; i++) { 99 | LUcolj[i] = LU_[i][j]; 100 | } 101 | 102 | // Apply previous transformations. 103 | 104 | for (int i = 0; i < m; i++) { 105 | LUrowi = LU_[i]; 106 | 107 | // Most of the time is spent in the following dot product. 108 | 109 | int kmax = min(i,j); 110 | double s = 0.0; 111 | for (int k = 0; k < kmax; k++) { 112 | s += LUrowi[k]*LUcolj[k]; 113 | } 114 | 115 | LUrowi[j] = LUcolj[i] -= s; 116 | } 117 | 118 | // Find pivot and exchange if necessary. 119 | 120 | int p = j; 121 | for (int i = j+1; i < m; i++) { 122 | if (abs(LUcolj[i]) > abs(LUcolj[p])) { 123 | p = i; 124 | } 125 | } 126 | if (p != j) { 127 | int k=0; 128 | for (k = 0; k < n; k++) { 129 | double t = LU_[p][k]; 130 | LU_[p][k] = LU_[j][k]; 131 | LU_[j][k] = t; 132 | } 133 | k = piv[p]; 134 | piv[p] = piv[j]; 135 | piv[j] = k; 136 | pivsign = -pivsign; 137 | } 138 | 139 | // Compute multipliers. 140 | 141 | if ((j < m) && (LU_[j][j] != 0.0)) { 142 | for (int i = j+1; i < m; i++) { 143 | LU_[i][j] /= LU_[j][j]; 144 | } 145 | } 146 | } 147 | } 148 | 149 | 150 | /** Is the matrix nonsingular? 151 | @return 1 (true) if upper triangular factor U (and hence A) 152 | is nonsingular, 0 otherwise. 153 | */ 154 | 155 | int isNonsingular () { 156 | for (int j = 0; j < n; j++) { 157 | if (LU_[j][j] == 0) 158 | return 0; 159 | } 160 | return 1; 161 | } 162 | 163 | /** Return lower triangular factor 164 | @return L 165 | */ 166 | 167 | Array2D getL () { 168 | Array2D L_(m,n); 169 | for (int i = 0; i < m; i++) { 170 | for (int j = 0; j < n; j++) { 171 | if (i > j) { 172 | L_[i][j] = LU_[i][j]; 173 | } else if (i == j) { 174 | L_[i][j] = 1.0; 175 | } else { 176 | L_[i][j] = 0.0; 177 | } 178 | } 179 | } 180 | return L_; 181 | } 182 | 183 | /** Return upper triangular factor 184 | @return U portion of LU factorization. 185 | */ 186 | 187 | Array2D getU () { 188 | Array2D U_(n,n); 189 | for (int i = 0; i < n; i++) { 190 | for (int j = 0; j < n; j++) { 191 | if (i <= j) { 192 | U_[i][j] = LU_[i][j]; 193 | } else { 194 | U_[i][j] = 0.0; 195 | } 196 | } 197 | } 198 | return U_; 199 | } 200 | 201 | /** Return pivot permutation vector 202 | @return piv 203 | */ 204 | 205 | Array1D getPivot () { 206 | return piv; 207 | } 208 | 209 | 210 | /** Compute determinant using LU factors. 211 | @return determinant of A, or 0 if A is not square. 212 | */ 213 | 214 | Real det () { 215 | if (m != n) { 216 | return Real(0); 217 | } 218 | Real d = Real(pivsign); 219 | for (int j = 0; j < n; j++) { 220 | d *= LU_[j][j]; 221 | } 222 | return d; 223 | } 224 | 225 | /** Solve A*X = B 226 | @param B A Matrix with as many rows as A and any number of columns. 227 | @return X so that L*U*X = B(piv,:), if B is nonconformant, returns 228 | 0x0 (null) array. 229 | */ 230 | 231 | Array2D solve (const Array2D &B) 232 | { 233 | 234 | /* Dimensions: A is mxn, X is nxk, B is mxk */ 235 | 236 | if (B.dim1() != m) { 237 | return Array2D(0,0); 238 | } 239 | if (!isNonsingular()) { 240 | return Array2D(0,0); 241 | } 242 | 243 | // Copy right hand side with pivoting 244 | int nx = B.dim2(); 245 | 246 | 247 | Array2D X = permute_copy(B, piv, 0, nx-1); 248 | 249 | // Solve L*Y = B(piv,:) 250 | for (int k = 0; k < n; k++) { 251 | for (int i = k+1; i < n; i++) { 252 | for (int j = 0; j < nx; j++) { 253 | X[i][j] -= X[k][j]*LU_[i][k]; 254 | } 255 | } 256 | } 257 | // Solve U*X = Y; 258 | for (int k = n-1; k >= 0; k--) { 259 | for (int j = 0; j < nx; j++) { 260 | X[k][j] /= LU_[k][k]; 261 | } 262 | for (int i = 0; i < k; i++) { 263 | for (int j = 0; j < nx; j++) { 264 | X[i][j] -= X[k][j]*LU_[i][k]; 265 | } 266 | } 267 | } 268 | return X; 269 | } 270 | 271 | 272 | /** Solve A*x = b, where x and b are vectors of length equal 273 | to the number of rows in A. 274 | 275 | @param b a vector (Array1D> of length equal to the first dimension 276 | of A. 277 | @return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant, 278 | returns 0x0 (null) array. 279 | */ 280 | 281 | Array1D solve (const Array1D &b) 282 | { 283 | 284 | /* Dimensions: A is mxn, X is nxk, B is mxk */ 285 | 286 | if (b.dim1() != m) { 287 | return Array1D(); 288 | } 289 | if (!isNonsingular()) { 290 | return Array1D(); 291 | } 292 | 293 | 294 | Array1D x = permute_copy(b, piv); 295 | 296 | // Solve L*Y = B(piv) 297 | for (int k = 0; k < n; k++) { 298 | for (int i = k+1; i < n; i++) { 299 | x[i] -= x[k]*LU_[i][k]; 300 | } 301 | } 302 | 303 | // Solve U*X = Y; 304 | for (int k = n-1; k >= 0; k--) { 305 | x[k] /= LU_[k][k]; 306 | for (int i = 0; i < k; i++) 307 | x[i] -= x[k]*LU_[i][k]; 308 | } 309 | 310 | 311 | return x; 312 | } 313 | 314 | }; /* class LU */ 315 | 316 | } /* namespace JAMA */ 317 | 318 | #endif 319 | /* JAMA_LU_H */ 320 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT): Linear Algebra Module 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_H 22 | #define TNT_H 23 | 24 | 25 | 26 | //--------------------------------------------------------------------- 27 | // Define this macro if you want TNT to track some of the out-of-bounds 28 | // indexing. This can encur a small run-time overhead, but is recommended 29 | // while developing code. It can be turned off for production runs. 30 | // 31 | // #define TNT_BOUNDS_CHECK 32 | //--------------------------------------------------------------------- 33 | // 34 | 35 | //#define TNT_BOUNDS_CHECK 36 | 37 | 38 | 39 | #include "tnt_version.h" 40 | #include "tnt_math_utils.h" 41 | #include "tnt_array1d.h" 42 | #include "tnt_array2d.h" 43 | #include "tnt_array3d.h" 44 | #include "tnt_array1d_utils.h" 45 | #include "tnt_array2d_utils.h" 46 | #include "tnt_array3d_utils.h" 47 | 48 | #include "tnt_fortran_array1d.h" 49 | #include "tnt_fortran_array2d.h" 50 | #include "tnt_fortran_array3d.h" 51 | #include "tnt_fortran_array1d_utils.h" 52 | #include "tnt_fortran_array2d_utils.h" 53 | #include "tnt_fortran_array3d_utils.h" 54 | 55 | #include "tnt_sparse_matrix_csr.h" 56 | 57 | #include "tnt_stopwatch.h" 58 | #include "tnt_subscript.h" 59 | #include "tnt_vec.h" 60 | #include "tnt_cmat.h" 61 | 62 | 63 | #endif 64 | // TNT_H 65 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_array1d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_ARRAY1D_H 23 | #define TNT_ARRAY1D_H 24 | 25 | //#include 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | 33 | #include "tnt_i_refvec.h" 34 | 35 | namespace TNT 36 | { 37 | 38 | template 39 | class Array1D 40 | { 41 | 42 | private: 43 | 44 | /* ... */ 45 | i_refvec v_; 46 | int n_; 47 | T* data_; /* this normally points to v_.begin(), but 48 | * could also point to a portion (subvector) 49 | * of v_. 50 | */ 51 | 52 | void copy_(T* p, const T* q, int len) const; 53 | void set_(T* begin, T* end, const T& val); 54 | 55 | 56 | public: 57 | 58 | typedef T value_type; 59 | 60 | 61 | Array1D(); 62 | explicit Array1D(int n); 63 | Array1D(int n, const T &a); 64 | Array1D(int n, T *a); 65 | inline Array1D(const Array1D &A); 66 | inline operator T*(); 67 | inline operator const T*(); 68 | inline Array1D & operator=(const T &a); 69 | inline Array1D & operator=(const Array1D &A); 70 | inline Array1D & ref(const Array1D &A); 71 | Array1D copy() const; 72 | Array1D & inject(const Array1D & A); 73 | inline T& operator[](int i); 74 | inline const T& operator[](int i) const; 75 | inline int dim1() const; 76 | inline int dim() const; 77 | ~Array1D(); 78 | 79 | 80 | /* ... extended interface ... */ 81 | 82 | inline int ref_count() const; 83 | inline Array1D subarray(int i0, int i1); 84 | 85 | }; 86 | 87 | 88 | 89 | 90 | template 91 | Array1D::Array1D() : v_(), n_(0), data_(0) {} 92 | 93 | template 94 | Array1D::Array1D(const Array1D &A) : v_(A.v_), n_(A.n_), 95 | data_(A.data_) 96 | { 97 | #ifdef TNT_DEBUG 98 | std::cout << "Created Array1D(const Array1D &A) \n"; 99 | #endif 100 | 101 | } 102 | 103 | 104 | template 105 | Array1D::Array1D(int n) : v_(n), n_(n), data_(v_.begin()) 106 | { 107 | #ifdef TNT_DEBUG 108 | std::cout << "Created Array1D(int n) \n"; 109 | #endif 110 | } 111 | 112 | template 113 | Array1D::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) 114 | { 115 | #ifdef TNT_DEBUG 116 | std::cout << "Created Array1D(int n, const T& val) \n"; 117 | #endif 118 | set_(data_, data_+ n, val); 119 | 120 | } 121 | 122 | template 123 | Array1D::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) 124 | { 125 | #ifdef TNT_DEBUG 126 | std::cout << "Created Array1D(int n, T* a) \n"; 127 | #endif 128 | } 129 | 130 | template 131 | inline Array1D::operator T*() 132 | { 133 | return &(v_[0]); 134 | } 135 | 136 | 137 | template 138 | inline Array1D::operator const T*() 139 | { 140 | return &(v_[0]); 141 | } 142 | 143 | 144 | 145 | template 146 | inline T& Array1D::operator[](int i) 147 | { 148 | #ifdef TNT_BOUNDS_CHECK 149 | assert(i>= 0); 150 | assert(i < n_); 151 | #endif 152 | return data_[i]; 153 | } 154 | 155 | template 156 | inline const T& Array1D::operator[](int i) const 157 | { 158 | #ifdef TNT_BOUNDS_CHECK 159 | assert(i>= 0); 160 | assert(i < n_); 161 | #endif 162 | return data_[i]; 163 | } 164 | 165 | 166 | 167 | 168 | template 169 | Array1D & Array1D::operator=(const T &a) 170 | { 171 | set_(data_, data_+n_, a); 172 | return *this; 173 | } 174 | 175 | template 176 | Array1D Array1D::copy() const 177 | { 178 | Array1D A( n_); 179 | copy_(A.data_, data_, n_); 180 | 181 | return A; 182 | } 183 | 184 | 185 | template 186 | Array1D & Array1D::inject(const Array1D &A) 187 | { 188 | if (A.n_ == n_) 189 | copy_(data_, A.data_, n_); 190 | 191 | return *this; 192 | } 193 | 194 | 195 | 196 | 197 | 198 | template 199 | Array1D & Array1D::ref(const Array1D &A) 200 | { 201 | if (this != &A) 202 | { 203 | v_ = A.v_; /* operator= handles the reference counting. */ 204 | n_ = A.n_; 205 | data_ = A.data_; 206 | 207 | } 208 | return *this; 209 | } 210 | 211 | template 212 | Array1D & Array1D::operator=(const Array1D &A) 213 | { 214 | return ref(A); 215 | } 216 | 217 | template 218 | inline int Array1D::dim1() const { return n_; } 219 | 220 | template 221 | inline int Array1D::dim() const { return n_; } 222 | 223 | template 224 | Array1D::~Array1D() {} 225 | 226 | 227 | /* ............................ exented interface ......................*/ 228 | 229 | template 230 | inline int Array1D::ref_count() const 231 | { 232 | return v_.ref_count(); 233 | } 234 | 235 | template 236 | inline Array1D Array1D::subarray(int i0, int i1) 237 | { 238 | if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) 239 | { 240 | Array1D X(*this); /* create a new instance of this array. */ 241 | X.n_ = i1-i0+1; 242 | X.data_ += i0; 243 | 244 | return X; 245 | } 246 | else 247 | { 248 | return Array1D(); 249 | } 250 | } 251 | 252 | 253 | /* private internal functions */ 254 | 255 | 256 | template 257 | void Array1D::set_(T* begin, T* end, const T& a) 258 | { 259 | for (T* p=begin; p 265 | void Array1D::copy_(T* p, const T* q, int len) const 266 | { 267 | T *end = p + len; 268 | while (p 24 | #include 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | template 31 | std::ostream& operator<<(std::ostream &s, const Array1D &A) 32 | { 33 | int N=A.dim1(); 34 | 35 | #ifdef TNT_DEBUG 36 | s << "addr: " << (void *) &A[0] << "\n"; 37 | #endif 38 | s << N << "\n"; 39 | for (int j=0; j 49 | std::istream& operator>>(std::istream &s, Array1D &A) 50 | { 51 | int N; 52 | s >> N; 53 | 54 | Array1D B(N); 55 | for (int i=0; i> B[i]; 57 | A = B; 58 | return s; 59 | } 60 | 61 | 62 | 63 | template 64 | Array1D operator+(const Array1D &A, const Array1D &B) 65 | { 66 | int n = A.dim1(); 67 | 68 | if (B.dim1() != n ) 69 | return Array1D(); 70 | 71 | else 72 | { 73 | Array1D C(n); 74 | 75 | for (int i=0; i 86 | Array1D operator-(const Array1D &A, const Array1D &B) 87 | { 88 | int n = A.dim1(); 89 | 90 | if (B.dim1() != n ) 91 | return Array1D(); 92 | 93 | else 94 | { 95 | Array1D C(n); 96 | 97 | for (int i=0; i 107 | Array1D operator*(const Array1D &A, const Array1D &B) 108 | { 109 | int n = A.dim1(); 110 | 111 | if (B.dim1() != n ) 112 | return Array1D(); 113 | 114 | else 115 | { 116 | Array1D C(n); 117 | 118 | for (int i=0; i 128 | Array1D operator/(const Array1D &A, const Array1D &B) 129 | { 130 | int n = A.dim1(); 131 | 132 | if (B.dim1() != n ) 133 | return Array1D(); 134 | 135 | else 136 | { 137 | Array1D C(n); 138 | 139 | for (int i=0; i 156 | Array1D& operator+=(Array1D &A, const Array1D &B) 157 | { 158 | int n = A.dim1(); 159 | 160 | if (B.dim1() == n) 161 | { 162 | for (int i=0; i 174 | Array1D& operator-=(Array1D &A, const Array1D &B) 175 | { 176 | int n = A.dim1(); 177 | 178 | if (B.dim1() == n) 179 | { 180 | for (int i=0; i 191 | Array1D& operator*=(Array1D &A, const Array1D &B) 192 | { 193 | int n = A.dim1(); 194 | 195 | if (B.dim1() == n) 196 | { 197 | for (int i=0; i 209 | Array1D& operator/=(Array1D &A, const Array1D &B) 210 | { 211 | int n = A.dim1(); 212 | 213 | if (B.dim1() == n) 214 | { 215 | for (int i=0; i 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | 31 | #include "tnt_array1d.h" 32 | 33 | namespace TNT 34 | { 35 | 36 | template 37 | class Array2D 38 | { 39 | 40 | 41 | private: 42 | 43 | 44 | 45 | Array1D data_; 46 | Array1D v_; 47 | int m_; 48 | int n_; 49 | 50 | public: 51 | 52 | typedef T value_type; 53 | Array2D(); 54 | Array2D(int m, int n); 55 | Array2D(int m, int n, T *a); 56 | Array2D(int m, int n, const T &a); 57 | inline Array2D(const Array2D &A); 58 | inline operator T**(); 59 | inline operator const T**(); 60 | inline Array2D & operator=(const T &a); 61 | inline Array2D & operator=(const Array2D &A); 62 | inline Array2D & ref(const Array2D &A); 63 | Array2D copy() const; 64 | Array2D & inject(const Array2D & A); 65 | inline T* operator[](int i); 66 | inline const T* operator[](int i) const; 67 | inline int dim1() const; 68 | inline int dim2() const; 69 | ~Array2D(); 70 | 71 | /* extended interface (not part of the standard) */ 72 | 73 | 74 | inline int ref_count(); 75 | inline int ref_count_data(); 76 | inline int ref_count_dim1(); 77 | Array2D subarray(int i0, int i1, int j0, int j1); 78 | 79 | }; 80 | 81 | 82 | template 83 | Array2D::Array2D() : data_(), v_(), m_(0), n_(0) {} 84 | 85 | template 86 | Array2D::Array2D(const Array2D &A) : data_(A.data_), v_(A.v_), 87 | m_(A.m_), n_(A.n_) {} 88 | 89 | 90 | 91 | 92 | template 93 | Array2D::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n) 94 | { 95 | if (m>0 && n>0) 96 | { 97 | T* p = &(data_[0]); 98 | for (int i=0; i 109 | Array2D::Array2D(int m, int n, const T &val) : data_(m*n), v_(m), 110 | m_(m), n_(n) 111 | { 112 | if (m>0 && n>0) 113 | { 114 | data_ = val; 115 | T* p = &(data_[0]); 116 | for (int i=0; i 125 | Array2D::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n) 126 | { 127 | if (m>0 && n>0) 128 | { 129 | T* p = &(data_[0]); 130 | 131 | for (int i=0; i 141 | inline T* Array2D::operator[](int i) 142 | { 143 | #ifdef TNT_BOUNDS_CHECK 144 | assert(i >= 0); 145 | assert(i < m_); 146 | #endif 147 | 148 | return v_[i]; 149 | 150 | } 151 | 152 | 153 | template 154 | inline const T* Array2D::operator[](int i) const 155 | { 156 | #ifdef TNT_BOUNDS_CHECK 157 | assert(i >= 0); 158 | assert(i < m_); 159 | #endif 160 | 161 | return v_[i]; 162 | 163 | } 164 | 165 | template 166 | Array2D & Array2D::operator=(const T &a) 167 | { 168 | /* non-optimzied, but will work with subarrays in future verions */ 169 | 170 | for (int i=0; i 180 | Array2D Array2D::copy() const 181 | { 182 | Array2D A(m_, n_); 183 | 184 | for (int i=0; i 194 | Array2D & Array2D::inject(const Array2D &A) 195 | { 196 | if (A.m_ == m_ && A.n_ == n_) 197 | { 198 | for (int i=0; i 209 | Array2D & Array2D::ref(const Array2D &A) 210 | { 211 | if (this != &A) 212 | { 213 | v_ = A.v_; 214 | data_ = A.data_; 215 | m_ = A.m_; 216 | n_ = A.n_; 217 | 218 | } 219 | return *this; 220 | } 221 | 222 | 223 | 224 | template 225 | Array2D & Array2D::operator=(const Array2D &A) 226 | { 227 | return ref(A); 228 | } 229 | 230 | template 231 | inline int Array2D::dim1() const { return m_; } 232 | 233 | template 234 | inline int Array2D::dim2() const { return n_; } 235 | 236 | 237 | template 238 | Array2D::~Array2D() {} 239 | 240 | 241 | 242 | 243 | template 244 | inline Array2D::operator T**() 245 | { 246 | return &(v_[0]); 247 | } 248 | template 249 | inline Array2D::operator const T**() 250 | { 251 | return &(v_[0]); 252 | } 253 | 254 | /* ............... extended interface ............... */ 255 | /** 256 | Create a new view to a subarray defined by the boundaries 257 | [i0][i0] and [i1][j1]. The size of the subarray is 258 | (i1-i0) by (j1-j0). If either of these lengths are zero 259 | or negative, the subarray view is null. 260 | 261 | */ 262 | template 263 | Array2D Array2D::subarray(int i0, int i1, int j0, int j1) 264 | { 265 | Array2D A; 266 | int m = i1-i0+1; 267 | int n = j1-j0+1; 268 | 269 | /* if either length is zero or negative, this is an invalide 270 | subarray. return a null view. 271 | */ 272 | if (m<1 || n<1) 273 | return A; 274 | 275 | A.data_ = data_; 276 | A.m_ = m; 277 | A.n_ = n; 278 | A.v_ = Array1D(m); 279 | T* p = &(data_[0]) + i0 * n_ + j0; 280 | for (int i=0; i 289 | inline int Array2D::ref_count() 290 | { 291 | return ref_count_data(); 292 | } 293 | 294 | 295 | 296 | template 297 | inline int Array2D::ref_count_data() 298 | { 299 | return data_.ref_count(); 300 | } 301 | 302 | template 303 | inline int Array2D::ref_count_dim1() 304 | { 305 | return v_.ref_count(); 306 | } 307 | 308 | 309 | 310 | 311 | } /* namespace TNT */ 312 | 313 | #endif 314 | /* TNT_ARRAY2D_H */ 315 | 316 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_array2d_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_ARRAY2D_UTILS_H 22 | #define TNT_ARRAY2D_UTILS_H 23 | 24 | #include 25 | #include 26 | 27 | namespace TNT 28 | { 29 | 30 | 31 | template 32 | std::ostream& operator<<(std::ostream &s, const Array2D &A) 33 | { 34 | int M=A.dim1(); 35 | int N=A.dim2(); 36 | 37 | s << M << " " << N << "\n"; 38 | 39 | for (int i=0; i 53 | std::istream& operator>>(std::istream &s, Array2D &A) 54 | { 55 | 56 | int M, N; 57 | 58 | s >> M >> N; 59 | 60 | Array2D B(M,N); 61 | 62 | for (int i=0; i> B[i][j]; 66 | } 67 | 68 | A = B; 69 | return s; 70 | } 71 | 72 | 73 | template 74 | Array2D operator+(const Array2D &A, const Array2D &B) 75 | { 76 | int m = A.dim1(); 77 | int n = A.dim2(); 78 | 79 | if (B.dim1() != m || B.dim2() != n ) 80 | return Array2D(); 81 | 82 | else 83 | { 84 | Array2D C(m,n); 85 | 86 | for (int i=0; i 96 | Array2D operator-(const Array2D &A, const Array2D &B) 97 | { 98 | int m = A.dim1(); 99 | int n = A.dim2(); 100 | 101 | if (B.dim1() != m || B.dim2() != n ) 102 | return Array2D(); 103 | 104 | else 105 | { 106 | Array2D C(m,n); 107 | 108 | for (int i=0; i 119 | Array2D operator*(const Array2D &A, const Array2D &B) 120 | { 121 | int m = A.dim1(); 122 | int n = A.dim2(); 123 | 124 | if (B.dim1() != m || B.dim2() != n ) 125 | return Array2D(); 126 | 127 | else 128 | { 129 | Array2D C(m,n); 130 | 131 | for (int i=0; i 144 | Array2D operator/(const Array2D &A, const Array2D &B) 145 | { 146 | int m = A.dim1(); 147 | int n = A.dim2(); 148 | 149 | if (B.dim1() != m || B.dim2() != n ) 150 | return Array2D(); 151 | 152 | else 153 | { 154 | Array2D C(m,n); 155 | 156 | for (int i=0; i 170 | Array2D& operator+=(Array2D &A, const Array2D &B) 171 | { 172 | int m = A.dim1(); 173 | int n = A.dim2(); 174 | 175 | if (B.dim1() == m || B.dim2() == n ) 176 | { 177 | for (int i=0; i 189 | Array2D& operator-=(Array2D &A, const Array2D &B) 190 | { 191 | int m = A.dim1(); 192 | int n = A.dim2(); 193 | 194 | if (B.dim1() == m || B.dim2() == n ) 195 | { 196 | for (int i=0; i 208 | Array2D& operator*=(Array2D &A, const Array2D &B) 209 | { 210 | int m = A.dim1(); 211 | int n = A.dim2(); 212 | 213 | if (B.dim1() == m || B.dim2() == n ) 214 | { 215 | for (int i=0; i 229 | Array2D& operator/=(Array2D &A, const Array2D &B) 230 | { 231 | int m = A.dim1(); 232 | int n = A.dim2(); 233 | 234 | if (B.dim1() == m || B.dim2() == n ) 235 | { 236 | for (int i=0; i 259 | Array2D matmult(const Array2D &A, const Array2D &B) 260 | { 261 | if (A.dim2() != B.dim1()) 262 | return Array2D(); 263 | 264 | int M = A.dim1(); 265 | int N = A.dim2(); 266 | int K = B.dim2(); 267 | 268 | Array2D C(M,K); 269 | 270 | for (int i=0; i 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | 31 | #include "tnt_array1d.h" 32 | #include "tnt_array2d.h" 33 | 34 | namespace TNT 35 | { 36 | 37 | template 38 | class Array3D 39 | { 40 | 41 | 42 | private: 43 | Array1D data_; 44 | Array2D v_; 45 | int m_; 46 | int n_; 47 | int g_; 48 | 49 | 50 | public: 51 | 52 | typedef T value_type; 53 | 54 | Array3D(); 55 | Array3D(int m, int n, int g); 56 | Array3D(int m, int n, int g, T val); 57 | Array3D(int m, int n, int g, T *a); 58 | 59 | inline operator T***(); 60 | inline operator const T***(); 61 | inline Array3D(const Array3D &A); 62 | inline Array3D & operator=(const T &a); 63 | inline Array3D & operator=(const Array3D &A); 64 | inline Array3D & ref(const Array3D &A); 65 | Array3D copy() const; 66 | Array3D & inject(const Array3D & A); 67 | 68 | inline T** operator[](int i); 69 | inline const T* const * operator[](int i) const; 70 | inline int dim1() const; 71 | inline int dim2() const; 72 | inline int dim3() const; 73 | ~Array3D(); 74 | 75 | /* extended interface */ 76 | 77 | inline int ref_count(){ return data_.ref_count(); } 78 | Array3D subarray(int i0, int i1, int j0, int j1, 79 | int k0, int k1); 80 | }; 81 | 82 | template 83 | Array3D::Array3D() : data_(), v_(), m_(0), n_(0) {} 84 | 85 | template 86 | Array3D::Array3D(const Array3D &A) : data_(A.data_), 87 | v_(A.v_), m_(A.m_), n_(A.n_), g_(A.g_) 88 | { 89 | } 90 | 91 | 92 | 93 | template 94 | Array3D::Array3D(int m, int n, int g) : data_(m*n*g), v_(m,n), 95 | m_(m), n_(n), g_(g) 96 | { 97 | 98 | if (m>0 && n>0 && g>0) 99 | { 100 | T* p = & (data_[0]); 101 | int ng = n_*g_; 102 | 103 | for (int i=0; i 115 | Array3D::Array3D(int m, int n, int g, T val) : data_(m*n*g, val), 116 | v_(m,n), m_(m), n_(n), g_(g) 117 | { 118 | if (m>0 && n>0 && g>0) 119 | { 120 | 121 | T* p = & (data_[0]); 122 | int ng = n_*g_; 123 | 124 | for (int i=0; i 136 | Array3D::Array3D(int m, int n, int g, T* a) : 137 | data_(m*n*g, a), v_(m,n), m_(m), n_(n), g_(g) 138 | { 139 | 140 | if (m>0 && n>0 && g>0) 141 | { 142 | T* p = & (data_[0]); 143 | int ng = n_*g_; 144 | 145 | for (int i=0; i 157 | inline T** Array3D::operator[](int i) 158 | { 159 | #ifdef TNT_BOUNDS_CHECK 160 | assert(i >= 0); 161 | assert(i < m_); 162 | #endif 163 | 164 | return v_[i]; 165 | 166 | } 167 | 168 | template 169 | inline const T* const * Array3D::operator[](int i) const 170 | { return v_[i]; } 171 | 172 | template 173 | Array3D & Array3D::operator=(const T &a) 174 | { 175 | for (int i=0; i 184 | Array3D Array3D::copy() const 185 | { 186 | Array3D A(m_, n_, g_); 187 | for (int i=0; i 197 | Array3D & Array3D::inject(const Array3D &A) 198 | { 199 | if (A.m_ == m_ && A.n_ == n_ && A.g_ == g_) 200 | 201 | for (int i=0; i 212 | Array3D & Array3D::ref(const Array3D &A) 213 | { 214 | if (this != &A) 215 | { 216 | m_ = A.m_; 217 | n_ = A.n_; 218 | g_ = A.g_; 219 | v_ = A.v_; 220 | data_ = A.data_; 221 | } 222 | return *this; 223 | } 224 | 225 | template 226 | Array3D & Array3D::operator=(const Array3D &A) 227 | { 228 | return ref(A); 229 | } 230 | 231 | 232 | template 233 | inline int Array3D::dim1() const { return m_; } 234 | 235 | template 236 | inline int Array3D::dim2() const { return n_; } 237 | 238 | template 239 | inline int Array3D::dim3() const { return g_; } 240 | 241 | 242 | 243 | template 244 | Array3D::~Array3D() {} 245 | 246 | template 247 | inline Array3D::operator T***() 248 | { 249 | return v_; 250 | } 251 | 252 | 253 | template 254 | inline Array3D::operator const T***() 255 | { 256 | return v_; 257 | } 258 | 259 | /* extended interface */ 260 | template 261 | Array3D Array3D::subarray(int i0, int i1, int j0, 262 | int j1, int k0, int k1) 263 | { 264 | 265 | /* check that ranges are valid. */ 266 | if (!( 0 <= i0 && i0 <= i1 && i1 < m_ && 267 | 0 <= j0 && j0 <= j1 && j1 < n_ && 268 | 0 <= k0 && k0 <= k1 && k1 < g_)) 269 | return Array3D(); /* null array */ 270 | 271 | 272 | Array3D A; 273 | A.data_ = data_; 274 | A.m_ = i1-i0+1; 275 | A.n_ = j1-j0+1; 276 | A.g_ = k1-k0+1; 277 | A.v_ = Array2D(A.m_,A.n_); 278 | T* p = &(data_[0]) + i0*n_*g_ + j0*g_ + k0; 279 | 280 | for (int i=0; i 7 | #include 8 | 9 | namespace TNT 10 | { 11 | 12 | 13 | template 14 | std::ostream& operator<<(std::ostream &s, const Array3D &A) 15 | { 16 | int M=A.dim1(); 17 | int N=A.dim2(); 18 | int K=A.dim3(); 19 | 20 | s << M << " " << N << " " << K << "\n"; 21 | 22 | for (int i=0; i 38 | std::istream& operator>>(std::istream &s, Array3D &A) 39 | { 40 | 41 | int M, N, K; 42 | 43 | s >> M >> N >> K; 44 | 45 | Array3D B(M,N,K); 46 | 47 | for (int i=0; i> B[i][j][k]; 51 | 52 | A = B; 53 | return s; 54 | } 55 | 56 | 57 | 58 | template 59 | Array3D operator+(const Array3D &A, const Array3D &B) 60 | { 61 | int m = A.dim1(); 62 | int n = A.dim2(); 63 | int p = A.dim3(); 64 | 65 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 66 | return Array3D(); 67 | 68 | else 69 | { 70 | Array3D C(m,n,p); 71 | 72 | for (int i=0; i 83 | Array3D operator-(const Array3D &A, const Array3D &B) 84 | { 85 | int m = A.dim1(); 86 | int n = A.dim2(); 87 | int p = A.dim3(); 88 | 89 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 90 | return Array3D(); 91 | 92 | else 93 | { 94 | Array3D C(m,n,p); 95 | 96 | for (int i=0; i 109 | Array3D operator*(const Array3D &A, const Array3D &B) 110 | { 111 | int m = A.dim1(); 112 | int n = A.dim2(); 113 | int p = A.dim3(); 114 | 115 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 116 | return Array3D(); 117 | 118 | else 119 | { 120 | Array3D C(m,n,p); 121 | 122 | for (int i=0; i 133 | Array3D operator/(const Array3D &A, const Array3D &B) 134 | { 135 | int m = A.dim1(); 136 | int n = A.dim2(); 137 | int p = A.dim3(); 138 | 139 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 140 | return Array3D(); 141 | 142 | else 143 | { 144 | Array3D C(m,n,p); 145 | 146 | for (int i=0; i 158 | Array3D& operator+=(Array3D &A, const Array3D &B) 159 | { 160 | int m = A.dim1(); 161 | int n = A.dim2(); 162 | int p = A.dim3(); 163 | 164 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 165 | { 166 | for (int i=0; i 176 | Array3D& operator-=(Array3D &A, const Array3D &B) 177 | { 178 | int m = A.dim1(); 179 | int n = A.dim2(); 180 | int p = A.dim3(); 181 | 182 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 183 | { 184 | for (int i=0; i 194 | Array3D& operator*=(Array3D &A, const Array3D &B) 195 | { 196 | int m = A.dim1(); 197 | int n = A.dim2(); 198 | int p = A.dim3(); 199 | 200 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 201 | { 202 | for (int i=0; i 213 | Array3D& operator/=(Array3D &A, const Array3D &B) 214 | { 215 | int m = A.dim1(); 216 | int n = A.dim2(); 217 | int p = A.dim3(); 218 | 219 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 220 | { 221 | for (int i=0; i 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | 33 | #include "tnt_i_refvec.h" 34 | 35 | namespace TNT 36 | { 37 | 38 | template 39 | class Fortran_Array1D 40 | { 41 | 42 | private: 43 | 44 | i_refvec v_; 45 | int n_; 46 | T* data_; /* this normally points to v_.begin(), but 47 | * could also point to a portion (subvector) 48 | * of v_. 49 | */ 50 | 51 | void initialize_(int n); 52 | void copy_(T* p, const T* q, int len) const; 53 | void set_(T* begin, T* end, const T& val); 54 | 55 | 56 | public: 57 | 58 | typedef T value_type; 59 | 60 | 61 | Fortran_Array1D(); 62 | explicit Fortran_Array1D(int n); 63 | Fortran_Array1D(int n, const T &a); 64 | Fortran_Array1D(int n, T *a); 65 | inline Fortran_Array1D(const Fortran_Array1D &A); 66 | inline Fortran_Array1D & operator=(const T &a); 67 | inline Fortran_Array1D & operator=(const Fortran_Array1D &A); 68 | inline Fortran_Array1D & ref(const Fortran_Array1D &A); 69 | Fortran_Array1D copy() const; 70 | Fortran_Array1D & inject(const Fortran_Array1D & A); 71 | inline T& operator()(int i); 72 | inline const T& operator()(int i) const; 73 | inline int dim1() const; 74 | inline int dim() const; 75 | ~Fortran_Array1D(); 76 | 77 | 78 | /* ... extended interface ... */ 79 | 80 | inline int ref_count() const; 81 | inline Fortran_Array1D subarray(int i0, int i1); 82 | 83 | }; 84 | 85 | 86 | 87 | 88 | template 89 | Fortran_Array1D::Fortran_Array1D() : v_(), n_(0), data_(0) {} 90 | 91 | template 92 | Fortran_Array1D::Fortran_Array1D(const Fortran_Array1D &A) : v_(A.v_), n_(A.n_), 93 | data_(A.data_) 94 | { 95 | #ifdef TNT_DEBUG 96 | std::cout << "Created Fortran_Array1D(const Fortran_Array1D &A) \n"; 97 | #endif 98 | 99 | } 100 | 101 | 102 | template 103 | Fortran_Array1D::Fortran_Array1D(int n) : v_(n), n_(n), data_(v_.begin()) 104 | { 105 | #ifdef TNT_DEBUG 106 | std::cout << "Created Fortran_Array1D(int n) \n"; 107 | #endif 108 | } 109 | 110 | template 111 | Fortran_Array1D::Fortran_Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) 112 | { 113 | #ifdef TNT_DEBUG 114 | std::cout << "Created Fortran_Array1D(int n, const T& val) \n"; 115 | #endif 116 | set_(data_, data_+ n, val); 117 | 118 | } 119 | 120 | template 121 | Fortran_Array1D::Fortran_Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) 122 | { 123 | #ifdef TNT_DEBUG 124 | std::cout << "Created Fortran_Array1D(int n, T* a) \n"; 125 | #endif 126 | } 127 | 128 | template 129 | inline T& Fortran_Array1D::operator()(int i) 130 | { 131 | #ifdef TNT_BOUNDS_CHECK 132 | assert(i>= 1); 133 | assert(i <= n_); 134 | #endif 135 | return data_[i-1]; 136 | } 137 | 138 | template 139 | inline const T& Fortran_Array1D::operator()(int i) const 140 | { 141 | #ifdef TNT_BOUNDS_CHECK 142 | assert(i>= 1); 143 | assert(i <= n_); 144 | #endif 145 | return data_[i-1]; 146 | } 147 | 148 | 149 | 150 | 151 | template 152 | Fortran_Array1D & Fortran_Array1D::operator=(const T &a) 153 | { 154 | set_(data_, data_+n_, a); 155 | return *this; 156 | } 157 | 158 | template 159 | Fortran_Array1D Fortran_Array1D::copy() const 160 | { 161 | Fortran_Array1D A( n_); 162 | copy_(A.data_, data_, n_); 163 | 164 | return A; 165 | } 166 | 167 | 168 | template 169 | Fortran_Array1D & Fortran_Array1D::inject(const Fortran_Array1D &A) 170 | { 171 | if (A.n_ == n_) 172 | copy_(data_, A.data_, n_); 173 | 174 | return *this; 175 | } 176 | 177 | 178 | 179 | 180 | 181 | template 182 | Fortran_Array1D & Fortran_Array1D::ref(const Fortran_Array1D &A) 183 | { 184 | if (this != &A) 185 | { 186 | v_ = A.v_; /* operator= handles the reference counting. */ 187 | n_ = A.n_; 188 | data_ = A.data_; 189 | 190 | } 191 | return *this; 192 | } 193 | 194 | template 195 | Fortran_Array1D & Fortran_Array1D::operator=(const Fortran_Array1D &A) 196 | { 197 | return ref(A); 198 | } 199 | 200 | template 201 | inline int Fortran_Array1D::dim1() const { return n_; } 202 | 203 | template 204 | inline int Fortran_Array1D::dim() const { return n_; } 205 | 206 | template 207 | Fortran_Array1D::~Fortran_Array1D() {} 208 | 209 | 210 | /* ............................ exented interface ......................*/ 211 | 212 | template 213 | inline int Fortran_Array1D::ref_count() const 214 | { 215 | return v_.ref_count(); 216 | } 217 | 218 | template 219 | inline Fortran_Array1D Fortran_Array1D::subarray(int i0, int i1) 220 | { 221 | #ifdef TNT_DEBUG 222 | std::cout << "entered subarray. \n"; 223 | #endif 224 | if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) 225 | { 226 | Fortran_Array1D X(*this); /* create a new instance of this array. */ 227 | X.n_ = i1-i0+1; 228 | X.data_ += i0; 229 | 230 | return X; 231 | } 232 | else 233 | { 234 | #ifdef TNT_DEBUG 235 | std::cout << "subarray: null return.\n"; 236 | #endif 237 | return Fortran_Array1D(); 238 | } 239 | } 240 | 241 | 242 | /* private internal functions */ 243 | 244 | 245 | template 246 | void Fortran_Array1D::set_(T* begin, T* end, const T& a) 247 | { 248 | for (T* p=begin; p 254 | void Fortran_Array1D::copy_(T* p, const T* q, int len) const 255 | { 256 | T *end = p + len; 257 | while (p 24 | 25 | namespace TNT 26 | { 27 | 28 | 29 | /** 30 | Write an array to a character outstream. Output format is one that can 31 | be read back in via the in-stream operator: one integer 32 | denoting the array dimension (n), followed by n elements, 33 | one per line. 34 | 35 | */ 36 | template 37 | std::ostream& operator<<(std::ostream &s, const Fortran_Array1D &A) 38 | { 39 | int N=A.dim1(); 40 | 41 | s << N << "\n"; 42 | for (int j=1; j<=N; j++) 43 | { 44 | s << A(j) << "\n"; 45 | } 46 | s << "\n"; 47 | 48 | return s; 49 | } 50 | 51 | /** 52 | Read an array from a character stream. Input format 53 | is one integer, denoting the dimension (n), followed 54 | by n whitespace-separated elments. Newlines are ignored 55 | 56 |

57 | Note: the array being read into references new memory 58 | storage. If the intent is to fill an existing conformant 59 | array, use cin >> B; A.inject(B) ); 60 | instead or read the elements in one-a-time by hand. 61 | 62 | @param s the charater to read from (typically std::in) 63 | @param A the array to read into. 64 | */ 65 | template 66 | std::istream& operator>>(std::istream &s, Fortran_Array1D &A) 67 | { 68 | int N; 69 | s >> N; 70 | 71 | Fortran_Array1D B(N); 72 | for (int i=1; i<=N; i++) 73 | s >> B(i); 74 | A = B; 75 | return s; 76 | } 77 | 78 | 79 | template 80 | Fortran_Array1D operator+(const Fortran_Array1D &A, const Fortran_Array1D &B) 81 | { 82 | int n = A.dim1(); 83 | 84 | if (B.dim1() != n ) 85 | return Fortran_Array1D(); 86 | 87 | else 88 | { 89 | Fortran_Array1D C(n); 90 | 91 | for (int i=1; i<=n; i++) 92 | { 93 | C(i) = A(i) + B(i); 94 | } 95 | return C; 96 | } 97 | } 98 | 99 | 100 | 101 | template 102 | Fortran_Array1D operator-(const Fortran_Array1D &A, const Fortran_Array1D &B) 103 | { 104 | int n = A.dim1(); 105 | 106 | if (B.dim1() != n ) 107 | return Fortran_Array1D(); 108 | 109 | else 110 | { 111 | Fortran_Array1D C(n); 112 | 113 | for (int i=1; i<=n; i++) 114 | { 115 | C(i) = A(i) - B(i); 116 | } 117 | return C; 118 | } 119 | } 120 | 121 | 122 | template 123 | Fortran_Array1D operator*(const Fortran_Array1D &A, const Fortran_Array1D &B) 124 | { 125 | int n = A.dim1(); 126 | 127 | if (B.dim1() != n ) 128 | return Fortran_Array1D(); 129 | 130 | else 131 | { 132 | Fortran_Array1D C(n); 133 | 134 | for (int i=1; i<=n; i++) 135 | { 136 | C(i) = A(i) * B(i); 137 | } 138 | return C; 139 | } 140 | } 141 | 142 | 143 | template 144 | Fortran_Array1D operator/(const Fortran_Array1D &A, const Fortran_Array1D &B) 145 | { 146 | int n = A.dim1(); 147 | 148 | if (B.dim1() != n ) 149 | return Fortran_Array1D(); 150 | 151 | else 152 | { 153 | Fortran_Array1D C(n); 154 | 155 | for (int i=1; i<=n; i++) 156 | { 157 | C(i) = A(i) / B(i); 158 | } 159 | return C; 160 | } 161 | } 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | template 172 | Fortran_Array1D& operator+=(Fortran_Array1D &A, const Fortran_Array1D &B) 173 | { 174 | int n = A.dim1(); 175 | 176 | if (B.dim1() == n) 177 | { 178 | for (int i=1; i<=n; i++) 179 | { 180 | A(i) += B(i); 181 | } 182 | } 183 | return A; 184 | } 185 | 186 | 187 | 188 | 189 | template 190 | Fortran_Array1D& operator-=(Fortran_Array1D &A, const Fortran_Array1D &B) 191 | { 192 | int n = A.dim1(); 193 | 194 | if (B.dim1() == n) 195 | { 196 | for (int i=1; i<=n; i++) 197 | { 198 | A(i) -= B(i); 199 | } 200 | } 201 | return A; 202 | } 203 | 204 | 205 | 206 | template 207 | Fortran_Array1D& operator*=(Fortran_Array1D &A, const Fortran_Array1D &B) 208 | { 209 | int n = A.dim1(); 210 | 211 | if (B.dim1() == n) 212 | { 213 | for (int i=1; i<=n; i++) 214 | { 215 | A(i) *= B(i); 216 | } 217 | } 218 | return A; 219 | } 220 | 221 | 222 | 223 | 224 | template 225 | Fortran_Array1D& operator/=(Fortran_Array1D &A, const Fortran_Array1D &B) 226 | { 227 | int n = A.dim1(); 228 | 229 | if (B.dim1() == n) 230 | { 231 | for (int i=1; i<=n; i++) 232 | { 233 | A(i) /= B(i); 234 | } 235 | } 236 | return A; 237 | } 238 | 239 | 240 | } // namespace TNT 241 | 242 | #endif 243 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_fortran_array2d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT): Two-dimensional Fortran numerical array 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_FORTRAN_ARRAY2D_H 23 | #define TNT_FORTRAN_ARRAY2D_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | #include "tnt_i_refvec.h" 33 | 34 | namespace TNT 35 | { 36 | 37 | template 38 | class Fortran_Array2D 39 | { 40 | 41 | 42 | private: 43 | i_refvec v_; 44 | int m_; 45 | int n_; 46 | T* data_; 47 | 48 | 49 | void initialize_(int n); 50 | void copy_(T* p, const T* q, int len); 51 | void set_(T* begin, T* end, const T& val); 52 | 53 | public: 54 | 55 | typedef T value_type; 56 | 57 | Fortran_Array2D(); 58 | Fortran_Array2D(int m, int n); 59 | Fortran_Array2D(int m, int n, T *a); 60 | Fortran_Array2D(int m, int n, const T &a); 61 | inline Fortran_Array2D(const Fortran_Array2D &A); 62 | inline Fortran_Array2D & operator=(const T &a); 63 | inline Fortran_Array2D & operator=(const Fortran_Array2D &A); 64 | inline Fortran_Array2D & ref(const Fortran_Array2D &A); 65 | Fortran_Array2D copy() const; 66 | Fortran_Array2D & inject(const Fortran_Array2D & A); 67 | inline T& operator()(int i, int j); 68 | inline const T& operator()(int i, int j) const ; 69 | inline int dim1() const; 70 | inline int dim2() const; 71 | ~Fortran_Array2D(); 72 | 73 | /* extended interface */ 74 | 75 | inline int ref_count() const; 76 | 77 | }; 78 | 79 | template 80 | Fortran_Array2D::Fortran_Array2D() : v_(), m_(0), n_(0), data_(0) {} 81 | 82 | 83 | template 84 | Fortran_Array2D::Fortran_Array2D(const Fortran_Array2D &A) : v_(A.v_), 85 | m_(A.m_), n_(A.n_), data_(A.data_) {} 86 | 87 | 88 | 89 | template 90 | Fortran_Array2D::Fortran_Array2D(int m, int n) : v_(m*n), m_(m), n_(n), 91 | data_(v_.begin()) {} 92 | 93 | template 94 | Fortran_Array2D::Fortran_Array2D(int m, int n, const T &val) : 95 | v_(m*n), m_(m), n_(n), data_(v_.begin()) 96 | { 97 | set_(data_, data_+m*n, val); 98 | } 99 | 100 | 101 | template 102 | Fortran_Array2D::Fortran_Array2D(int m, int n, T *a) : v_(a), 103 | m_(m), n_(n), data_(v_.begin()) {} 104 | 105 | 106 | 107 | 108 | template 109 | inline T& Fortran_Array2D::operator()(int i, int j) 110 | { 111 | #ifdef TNT_BOUNDS_CHECK 112 | assert(i >= 1); 113 | assert(i <= m_); 114 | assert(j >= 1); 115 | assert(j <= n_); 116 | #endif 117 | 118 | return v_[ (j-1)*m_ + (i-1) ]; 119 | 120 | } 121 | 122 | template 123 | inline const T& Fortran_Array2D::operator()(int i, int j) const 124 | { 125 | #ifdef TNT_BOUNDS_CHECK 126 | assert(i >= 1); 127 | assert(i <= m_); 128 | assert(j >= 1); 129 | assert(j <= n_); 130 | #endif 131 | 132 | return v_[ (j-1)*m_ + (i-1) ]; 133 | 134 | } 135 | 136 | 137 | template 138 | Fortran_Array2D & Fortran_Array2D::operator=(const T &a) 139 | { 140 | set_(data_, data_+m_*n_, a); 141 | return *this; 142 | } 143 | 144 | template 145 | Fortran_Array2D Fortran_Array2D::copy() const 146 | { 147 | 148 | Fortran_Array2D B(m_,n_); 149 | 150 | B.inject(*this); 151 | return B; 152 | } 153 | 154 | 155 | template 156 | Fortran_Array2D & Fortran_Array2D::inject(const Fortran_Array2D &A) 157 | { 158 | if (m_ == A.m_ && n_ == A.n_) 159 | copy_(data_, A.data_, m_*n_); 160 | 161 | return *this; 162 | } 163 | 164 | 165 | 166 | template 167 | Fortran_Array2D & Fortran_Array2D::ref(const Fortran_Array2D &A) 168 | { 169 | if (this != &A) 170 | { 171 | v_ = A.v_; 172 | m_ = A.m_; 173 | n_ = A.n_; 174 | data_ = A.data_; 175 | } 176 | return *this; 177 | } 178 | 179 | template 180 | Fortran_Array2D & Fortran_Array2D::operator=(const Fortran_Array2D &A) 181 | { 182 | return ref(A); 183 | } 184 | 185 | template 186 | inline int Fortran_Array2D::dim1() const { return m_; } 187 | 188 | template 189 | inline int Fortran_Array2D::dim2() const { return n_; } 190 | 191 | 192 | template 193 | Fortran_Array2D::~Fortran_Array2D() 194 | { 195 | } 196 | 197 | template 198 | inline int Fortran_Array2D::ref_count() const { return v_.ref_count(); } 199 | 200 | 201 | 202 | 203 | template 204 | void Fortran_Array2D::set_(T* begin, T* end, const T& a) 205 | { 206 | for (T* p=begin; p 212 | void Fortran_Array2D::copy_(T* p, const T* q, int len) 213 | { 214 | T *end = p + len; 215 | while (p 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | template 31 | std::ostream& operator<<(std::ostream &s, const Fortran_Array2D &A) 32 | { 33 | int M=A.dim1(); 34 | int N=A.dim2(); 35 | 36 | s << M << " " << N << "\n"; 37 | 38 | for (int i=1; i<=M; i++) 39 | { 40 | for (int j=1; j<=N; j++) 41 | { 42 | s << A(i,j) << " "; 43 | } 44 | s << "\n"; 45 | } 46 | 47 | 48 | return s; 49 | } 50 | 51 | template 52 | std::istream& operator>>(std::istream &s, Fortran_Array2D &A) 53 | { 54 | 55 | int M, N; 56 | 57 | s >> M >> N; 58 | 59 | Fortran_Array2D B(M,N); 60 | 61 | for (int i=1; i<=M; i++) 62 | for (int j=1; j<=N; j++) 63 | { 64 | s >> B(i,j); 65 | } 66 | 67 | A = B; 68 | return s; 69 | } 70 | 71 | 72 | 73 | 74 | template 75 | Fortran_Array2D operator+(const Fortran_Array2D &A, const Fortran_Array2D &B) 76 | { 77 | int m = A.dim1(); 78 | int n = A.dim2(); 79 | 80 | if (B.dim1() != m || B.dim2() != n ) 81 | return Fortran_Array2D(); 82 | 83 | else 84 | { 85 | Fortran_Array2D C(m,n); 86 | 87 | for (int i=1; i<=m; i++) 88 | { 89 | for (int j=1; j<=n; j++) 90 | C(i,j) = A(i,j) + B(i,j); 91 | } 92 | return C; 93 | } 94 | } 95 | 96 | template 97 | Fortran_Array2D operator-(const Fortran_Array2D &A, const Fortran_Array2D &B) 98 | { 99 | int m = A.dim1(); 100 | int n = A.dim2(); 101 | 102 | if (B.dim1() != m || B.dim2() != n ) 103 | return Fortran_Array2D(); 104 | 105 | else 106 | { 107 | Fortran_Array2D C(m,n); 108 | 109 | for (int i=1; i<=m; i++) 110 | { 111 | for (int j=1; j<=n; j++) 112 | C(i,j) = A(i,j) - B(i,j); 113 | } 114 | return C; 115 | } 116 | } 117 | 118 | 119 | template 120 | Fortran_Array2D operator*(const Fortran_Array2D &A, const Fortran_Array2D &B) 121 | { 122 | int m = A.dim1(); 123 | int n = A.dim2(); 124 | 125 | if (B.dim1() != m || B.dim2() != n ) 126 | return Fortran_Array2D(); 127 | 128 | else 129 | { 130 | Fortran_Array2D C(m,n); 131 | 132 | for (int i=1; i<=m; i++) 133 | { 134 | for (int j=1; j<=n; j++) 135 | C(i,j) = A(i,j) * B(i,j); 136 | } 137 | return C; 138 | } 139 | } 140 | 141 | 142 | template 143 | Fortran_Array2D operator/(const Fortran_Array2D &A, const Fortran_Array2D &B) 144 | { 145 | int m = A.dim1(); 146 | int n = A.dim2(); 147 | 148 | if (B.dim1() != m || B.dim2() != n ) 149 | return Fortran_Array2D(); 150 | 151 | else 152 | { 153 | Fortran_Array2D C(m,n); 154 | 155 | for (int i=1; i<=m; i++) 156 | { 157 | for (int j=1; j<=n; j++) 158 | C(i,j) = A(i,j) / B(i,j); 159 | } 160 | return C; 161 | } 162 | } 163 | 164 | 165 | 166 | template 167 | Fortran_Array2D& operator+=(Fortran_Array2D &A, const Fortran_Array2D &B) 168 | { 169 | int m = A.dim1(); 170 | int n = A.dim2(); 171 | 172 | if (B.dim1() == m || B.dim2() == n ) 173 | { 174 | for (int i=1; i<=m; i++) 175 | { 176 | for (int j=1; j<=n; j++) 177 | A(i,j) += B(i,j); 178 | } 179 | } 180 | return A; 181 | } 182 | 183 | template 184 | Fortran_Array2D& operator-=(Fortran_Array2D &A, const Fortran_Array2D &B) 185 | { 186 | int m = A.dim1(); 187 | int n = A.dim2(); 188 | 189 | if (B.dim1() == m || B.dim2() == n ) 190 | { 191 | for (int i=1; i<=m; i++) 192 | { 193 | for (int j=1; j<=n; j++) 194 | A(i,j) -= B(i,j); 195 | } 196 | } 197 | return A; 198 | } 199 | 200 | template 201 | Fortran_Array2D& operator*=(Fortran_Array2D &A, const Fortran_Array2D &B) 202 | { 203 | int m = A.dim1(); 204 | int n = A.dim2(); 205 | 206 | if (B.dim1() == m || B.dim2() == n ) 207 | { 208 | for (int i=1; i<=m; i++) 209 | { 210 | for (int j=1; j<=n; j++) 211 | A(i,j) *= B(i,j); 212 | } 213 | } 214 | return A; 215 | } 216 | 217 | template 218 | Fortran_Array2D& operator/=(Fortran_Array2D &A, const Fortran_Array2D &B) 219 | { 220 | int m = A.dim1(); 221 | int n = A.dim2(); 222 | 223 | if (B.dim1() == m || B.dim2() == n ) 224 | { 225 | for (int i=1; i<=m; i++) 226 | { 227 | for (int j=1; j<=n; j++) 228 | A(i,j) /= B(i,j); 229 | } 230 | } 231 | return A; 232 | } 233 | 234 | } // namespace TNT 235 | 236 | #endif 237 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_fortran_array3d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT): Three-dimensional Fortran numerical array 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_FORTRAN_ARRAY3D_H 23 | #define TNT_FORTRAN_ARRAY3D_H 24 | 25 | #include 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | #include "tnt_i_refvec.h" 31 | 32 | namespace TNT 33 | { 34 | 35 | template 36 | class Fortran_Array3D 37 | { 38 | 39 | 40 | private: 41 | 42 | 43 | i_refvec v_; 44 | int m_; 45 | int n_; 46 | int k_; 47 | T* data_; 48 | 49 | public: 50 | 51 | typedef T value_type; 52 | 53 | Fortran_Array3D(); 54 | Fortran_Array3D(int m, int n, int k); 55 | Fortran_Array3D(int m, int n, int k, T *a); 56 | Fortran_Array3D(int m, int n, int k, const T &a); 57 | inline Fortran_Array3D(const Fortran_Array3D &A); 58 | inline Fortran_Array3D & operator=(const T &a); 59 | inline Fortran_Array3D & operator=(const Fortran_Array3D &A); 60 | inline Fortran_Array3D & ref(const Fortran_Array3D &A); 61 | Fortran_Array3D copy() const; 62 | Fortran_Array3D & inject(const Fortran_Array3D & A); 63 | inline T& operator()(int i, int j, int k); 64 | inline const T& operator()(int i, int j, int k) const ; 65 | inline int dim1() const; 66 | inline int dim2() const; 67 | inline int dim3() const; 68 | inline int ref_count() const; 69 | ~Fortran_Array3D(); 70 | 71 | 72 | }; 73 | 74 | template 75 | Fortran_Array3D::Fortran_Array3D() : v_(), m_(0), n_(0), k_(0), data_(0) {} 76 | 77 | 78 | template 79 | Fortran_Array3D::Fortran_Array3D(const Fortran_Array3D &A) : 80 | v_(A.v_), m_(A.m_), n_(A.n_), k_(A.k_), data_(A.data_) {} 81 | 82 | 83 | 84 | template 85 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k) : 86 | v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) {} 87 | 88 | 89 | 90 | template 91 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k, const T &val) : 92 | v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) 93 | { 94 | for (T* p = data_; p < data_ + m*n*k; p++) 95 | *p = val; 96 | } 97 | 98 | template 99 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k, T *a) : 100 | v_(a), m_(m), n_(n), k_(k), data_(v_.begin()) {} 101 | 102 | 103 | 104 | 105 | template 106 | inline T& Fortran_Array3D::operator()(int i, int j, int k) 107 | { 108 | #ifdef TNT_BOUNDS_CHECK 109 | assert(i >= 1); 110 | assert(i <= m_); 111 | assert(j >= 1); 112 | assert(j <= n_); 113 | assert(k >= 1); 114 | assert(k <= k_); 115 | #endif 116 | 117 | return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; 118 | 119 | } 120 | 121 | template 122 | inline const T& Fortran_Array3D::operator()(int i, int j, int k) const 123 | { 124 | #ifdef TNT_BOUNDS_CHECK 125 | assert(i >= 1); 126 | assert(i <= m_); 127 | assert(j >= 1); 128 | assert(j <= n_); 129 | assert(k >= 1); 130 | assert(k <= k_); 131 | #endif 132 | 133 | return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; 134 | } 135 | 136 | 137 | template 138 | Fortran_Array3D & Fortran_Array3D::operator=(const T &a) 139 | { 140 | 141 | T *end = data_ + m_*n_*k_; 142 | 143 | for (T *p=data_; p != end; *p++ = a); 144 | 145 | return *this; 146 | } 147 | 148 | template 149 | Fortran_Array3D Fortran_Array3D::copy() const 150 | { 151 | 152 | Fortran_Array3D B(m_, n_, k_); 153 | B.inject(*this); 154 | return B; 155 | 156 | } 157 | 158 | 159 | template 160 | Fortran_Array3D & Fortran_Array3D::inject(const Fortran_Array3D &A) 161 | { 162 | 163 | if (m_ == A.m_ && n_ == A.n_ && k_ == A.k_) 164 | { 165 | T *p = data_; 166 | T *end = data_ + m_*n_*k_; 167 | const T* q = A.data_; 168 | for (; p < end; *p++ = *q++); 169 | } 170 | return *this; 171 | } 172 | 173 | 174 | 175 | 176 | template 177 | Fortran_Array3D & Fortran_Array3D::ref(const Fortran_Array3D &A) 178 | { 179 | 180 | if (this != &A) 181 | { 182 | v_ = A.v_; 183 | m_ = A.m_; 184 | n_ = A.n_; 185 | k_ = A.k_; 186 | data_ = A.data_; 187 | } 188 | return *this; 189 | } 190 | 191 | template 192 | Fortran_Array3D & Fortran_Array3D::operator=(const Fortran_Array3D &A) 193 | { 194 | return ref(A); 195 | } 196 | 197 | template 198 | inline int Fortran_Array3D::dim1() const { return m_; } 199 | 200 | template 201 | inline int Fortran_Array3D::dim2() const { return n_; } 202 | 203 | template 204 | inline int Fortran_Array3D::dim3() const { return k_; } 205 | 206 | 207 | template 208 | inline int Fortran_Array3D::ref_count() const 209 | { 210 | return v_.ref_count(); 211 | } 212 | 213 | template 214 | Fortran_Array3D::~Fortran_Array3D() 215 | { 216 | } 217 | 218 | 219 | } /* namespace TNT */ 220 | 221 | #endif 222 | /* TNT_FORTRAN_ARRAY3D_H */ 223 | 224 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_fortran_array3d_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_FORTRAN_ARRAY3D_UTILS_H 22 | #define TNT_FORTRAN_ARRAY3D_UTILS_H 23 | 24 | #include 25 | #include 26 | 27 | namespace TNT 28 | { 29 | 30 | 31 | template 32 | std::ostream& operator<<(std::ostream &s, const Fortran_Array3D &A) 33 | { 34 | int M=A.dim1(); 35 | int N=A.dim2(); 36 | int K=A.dim3(); 37 | 38 | s << M << " " << N << " " << K << "\n"; 39 | 40 | for (int i=1; i<=M; i++) 41 | { 42 | for (int j=1; j<=N; j++) 43 | { 44 | for (int k=1; k<=K; k++) 45 | s << A(i,j,k) << " "; 46 | s << "\n"; 47 | } 48 | s << "\n"; 49 | } 50 | 51 | 52 | return s; 53 | } 54 | 55 | template 56 | std::istream& operator>>(std::istream &s, Fortran_Array3D &A) 57 | { 58 | 59 | int M, N, K; 60 | 61 | s >> M >> N >> K; 62 | 63 | Fortran_Array3D B(M,N,K); 64 | 65 | for (int i=1; i<=M; i++) 66 | for (int j=1; j<=N; j++) 67 | for (int k=1; k<=K; k++) 68 | s >> B(i,j,k); 69 | 70 | A = B; 71 | return s; 72 | } 73 | 74 | 75 | template 76 | Fortran_Array3D operator+(const Fortran_Array3D &A, const Fortran_Array3D &B) 77 | { 78 | int m = A.dim1(); 79 | int n = A.dim2(); 80 | int p = A.dim3(); 81 | 82 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 83 | return Fortran_Array3D(); 84 | 85 | else 86 | { 87 | Fortran_Array3D C(m,n,p); 88 | 89 | for (int i=1; i<=m; i++) 90 | for (int j=1; j<=n; j++) 91 | for (int k=1; k<=p; k++) 92 | C(i,j,k) = A(i,j,k)+ B(i,j,k); 93 | 94 | return C; 95 | } 96 | } 97 | 98 | 99 | template 100 | Fortran_Array3D operator-(const Fortran_Array3D &A, const Fortran_Array3D &B) 101 | { 102 | int m = A.dim1(); 103 | int n = A.dim2(); 104 | int p = A.dim3(); 105 | 106 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 107 | return Fortran_Array3D(); 108 | 109 | else 110 | { 111 | Fortran_Array3D C(m,n,p); 112 | 113 | for (int i=1; i<=m; i++) 114 | for (int j=1; j<=n; j++) 115 | for (int k=1; k<=p; k++) 116 | C(i,j,k) = A(i,j,k)- B(i,j,k); 117 | 118 | return C; 119 | } 120 | } 121 | 122 | 123 | template 124 | Fortran_Array3D operator*(const Fortran_Array3D &A, const Fortran_Array3D &B) 125 | { 126 | int m = A.dim1(); 127 | int n = A.dim2(); 128 | int p = A.dim3(); 129 | 130 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 131 | return Fortran_Array3D(); 132 | 133 | else 134 | { 135 | Fortran_Array3D C(m,n,p); 136 | 137 | for (int i=1; i<=m; i++) 138 | for (int j=1; j<=n; j++) 139 | for (int k=1; k<=p; k++) 140 | C(i,j,k) = A(i,j,k)* B(i,j,k); 141 | 142 | return C; 143 | } 144 | } 145 | 146 | 147 | template 148 | Fortran_Array3D operator/(const Fortran_Array3D &A, const Fortran_Array3D &B) 149 | { 150 | int m = A.dim1(); 151 | int n = A.dim2(); 152 | int p = A.dim3(); 153 | 154 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 155 | return Fortran_Array3D(); 156 | 157 | else 158 | { 159 | Fortran_Array3D C(m,n,p); 160 | 161 | for (int i=1; i<=m; i++) 162 | for (int j=1; j<=n; j++) 163 | for (int k=1; k<=p; k++) 164 | C(i,j,k) = A(i,j,k)/ B(i,j,k); 165 | 166 | return C; 167 | } 168 | } 169 | 170 | 171 | template 172 | Fortran_Array3D& operator+=(Fortran_Array3D &A, const Fortran_Array3D &B) 173 | { 174 | int m = A.dim1(); 175 | int n = A.dim2(); 176 | int p = A.dim3(); 177 | 178 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 179 | { 180 | for (int i=1; i<=m; i++) 181 | for (int j=1; j<=n; j++) 182 | for (int k=1; k<=p; k++) 183 | A(i,j,k) += B(i,j,k); 184 | } 185 | 186 | return A; 187 | } 188 | 189 | 190 | template 191 | Fortran_Array3D& operator-=(Fortran_Array3D &A, const Fortran_Array3D &B) 192 | { 193 | int m = A.dim1(); 194 | int n = A.dim2(); 195 | int p = A.dim3(); 196 | 197 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 198 | { 199 | for (int i=1; i<=m; i++) 200 | for (int j=1; j<=n; j++) 201 | for (int k=1; k<=p; k++) 202 | A(i,j,k) -= B(i,j,k); 203 | } 204 | 205 | return A; 206 | } 207 | 208 | 209 | template 210 | Fortran_Array3D& operator*=(Fortran_Array3D &A, const Fortran_Array3D &B) 211 | { 212 | int m = A.dim1(); 213 | int n = A.dim2(); 214 | int p = A.dim3(); 215 | 216 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 217 | { 218 | for (int i=1; i<=m; i++) 219 | for (int j=1; j<=n; j++) 220 | for (int k=1; k<=p; k++) 221 | A(i,j,k) *= B(i,j,k); 222 | } 223 | 224 | return A; 225 | } 226 | 227 | 228 | template 229 | Fortran_Array3D& operator/=(Fortran_Array3D &A, const Fortran_Array3D &B) 230 | { 231 | int m = A.dim1(); 232 | int n = A.dim2(); 233 | int p = A.dim3(); 234 | 235 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 236 | { 237 | for (int i=1; i<=m; i++) 238 | for (int j=1; j<=n; j++) 239 | for (int k=1; k<=p; k++) 240 | A(i,j,k) /= B(i,j,k); 241 | } 242 | 243 | return A; 244 | } 245 | 246 | 247 | } // namespace TNT 248 | 249 | #endif 250 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_i_refvec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_I_REFVEC_H 23 | #define TNT_I_REFVEC_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | #ifndef NULL 33 | #define NULL 0 34 | #endif 35 | 36 | namespace TNT 37 | { 38 | /* 39 | Internal representation of ref-counted array. The TNT 40 | arrays all use this building block. 41 | 42 |

43 | If an array block is created by TNT, then every time 44 | an assignment is made, the left-hand-side reference 45 | is decreased by one, and the right-hand-side refernce 46 | count is increased by one. If the array block was 47 | external to TNT, the refernce count is a NULL pointer 48 | regardless of how many references are made, since the 49 | memory is not freed by TNT. 50 | 51 | 52 | 53 | */ 54 | template 55 | class i_refvec 56 | { 57 | 58 | 59 | private: 60 | T* data_; 61 | int *ref_count_; 62 | 63 | 64 | public: 65 | 66 | i_refvec(); 67 | explicit i_refvec(int n); 68 | inline i_refvec(T* data); 69 | inline i_refvec(const i_refvec &v); 70 | inline T* begin(); 71 | inline const T* begin() const; 72 | inline T& operator[](int i); 73 | inline const T& operator[](int i) const; 74 | inline i_refvec & operator=(const i_refvec &V); 75 | void copy_(T* p, const T* q, const T* e); 76 | void set_(T* p, const T* b, const T* e); 77 | inline int ref_count() const; 78 | inline int is_null() const; 79 | inline void destroy(); 80 | ~i_refvec(); 81 | 82 | }; 83 | 84 | template 85 | void i_refvec::copy_(T* p, const T* q, const T* e) 86 | { 87 | for (T* t=p; q 92 | i_refvec::i_refvec() : data_(NULL), ref_count_(NULL) {} 93 | 94 | /** 95 | In case n is 0 or negative, it does NOT call new. 96 | */ 97 | template 98 | i_refvec::i_refvec(int n) : data_(NULL), ref_count_(NULL) 99 | { 100 | if (n >= 1) 101 | { 102 | #ifdef TNT_DEBUG 103 | std::cout << "new data storage.\n"; 104 | #endif 105 | data_ = new T[n]; 106 | ref_count_ = new int; 107 | *ref_count_ = 1; 108 | } 109 | } 110 | 111 | template 112 | inline i_refvec::i_refvec(const i_refvec &V): data_(V.data_), 113 | ref_count_(V.ref_count_) 114 | { 115 | if (V.ref_count_ != NULL) 116 | (*(V.ref_count_))++; 117 | } 118 | 119 | 120 | template 121 | i_refvec::i_refvec(T* data) : data_(data), ref_count_(NULL) {} 122 | 123 | template 124 | inline T* i_refvec::begin() 125 | { 126 | return data_; 127 | } 128 | 129 | template 130 | inline const T& i_refvec::operator[](int i) const 131 | { 132 | return data_[i]; 133 | } 134 | 135 | template 136 | inline T& i_refvec::operator[](int i) 137 | { 138 | return data_[i]; 139 | } 140 | 141 | 142 | template 143 | inline const T* i_refvec::begin() const 144 | { 145 | return data_; 146 | } 147 | 148 | 149 | 150 | template 151 | i_refvec & i_refvec::operator=(const i_refvec &V) 152 | { 153 | if (this == &V) 154 | return *this; 155 | 156 | 157 | if (ref_count_ != NULL) 158 | { 159 | (*ref_count_) --; 160 | if ((*ref_count_) == 0) 161 | destroy(); 162 | } 163 | 164 | data_ = V.data_; 165 | ref_count_ = V.ref_count_; 166 | 167 | if (V.ref_count_ != NULL) 168 | (*(V.ref_count_))++; 169 | 170 | return *this; 171 | } 172 | 173 | template 174 | void i_refvec::destroy() 175 | { 176 | if (ref_count_ != NULL) 177 | { 178 | #ifdef TNT_DEBUG 179 | std::cout << "destorying data... \n"; 180 | #endif 181 | delete ref_count_; 182 | 183 | #ifdef TNT_DEBUG 184 | std::cout << "deleted ref_count_ ...\n"; 185 | #endif 186 | if (data_ != NULL) 187 | delete []data_; 188 | #ifdef TNT_DEBUG 189 | std::cout << "deleted data_[] ...\n"; 190 | #endif 191 | data_ = NULL; 192 | } 193 | } 194 | 195 | /* 196 | * return 1 is vector is empty, 0 otherwise 197 | * 198 | * if is_null() is false and ref_count() is 0, then 199 | * 200 | */ 201 | template 202 | int i_refvec::is_null() const 203 | { 204 | return (data_ == NULL ? 1 : 0); 205 | } 206 | 207 | /* 208 | * returns -1 if data is external, 209 | * returns 0 if a is NULL array, 210 | * otherwise returns the positive number of vectors sharing 211 | * this data space. 212 | */ 213 | template 214 | int i_refvec::ref_count() const 215 | { 216 | if (data_ == NULL) 217 | return 0; 218 | else 219 | return (ref_count_ != NULL ? *ref_count_ : -1) ; 220 | } 221 | 222 | template 223 | i_refvec::~i_refvec() 224 | { 225 | if (ref_count_ != NULL) 226 | { 227 | (*ref_count_)--; 228 | 229 | if (*ref_count_ == 0) 230 | destroy(); 231 | } 232 | } 233 | 234 | 235 | } /* namespace TNT */ 236 | 237 | 238 | 239 | 240 | 241 | #endif 242 | /* TNT_I_REFVEC_H */ 243 | 244 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_math_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_UTILS_H 2 | #define MATH_UTILS_H 3 | 4 | /* needed for fabs, sqrt() below */ 5 | #include 6 | 7 | 8 | 9 | namespace TNT 10 | { 11 | /** 12 | @returns hypotenuse of real (non-complex) scalars a and b by 13 | avoiding underflow/overflow 14 | using (a * sqrt( 1 + (b/a) * (b/a))), rather than 15 | sqrt(a*a + b*b). 16 | */ 17 | template 18 | Real hypot(const Real &a, const Real &b) 19 | { 20 | 21 | if (a== 0) 22 | return abs(b); 23 | else 24 | { 25 | Real c = b/a; 26 | return fabs(a) * sqrt(1 + c*c); 27 | } 28 | } 29 | } /* TNT namespace */ 30 | 31 | 32 | 33 | #endif 34 | /* MATH_UTILS_H */ 35 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_sparse_matrix_csr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_SPARSE_MATRIX_CSR_H 22 | #define TNT_SPARSE_MATRIX_CSR_H 23 | 24 | #include "tnt_array1d.h" 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | /** 31 | Read-only view of a sparse matrix in compressed-row storage 32 | format. Neither array elements (nonzeros) nor sparsity 33 | structure can be modified. If modifications are required, 34 | create a new view. 35 | 36 |

37 | Index values begin at 0. 38 | 39 |

40 | Storage requirements: An (m x n) matrix with 41 | nz nonzeros requires no more than ((T+I)*nz + M*I) 42 | bytes, where T is the size of data elements and 43 | I is the size of integers. 44 | 45 | 46 | */ 47 | template 48 | class Sparse_Matrix_CompRow { 49 | 50 | private: 51 | Array1D val_; // data values (nz_ elements) 52 | Array1D rowptr_; // row_ptr (dim_[0]+1 elements) 53 | Array1D colind_; // col_ind (nz_ elements) 54 | 55 | int dim1_; // number of rows 56 | int dim2_; // number of cols 57 | 58 | public: 59 | 60 | Sparse_Matrix_CompRow(const Sparse_Matrix_CompRow &S); 61 | Sparse_Matrix_CompRow(int M, int N, int nz, const T *val, 62 | int *r, int *c); 63 | 64 | 65 | 66 | inline const T& val(int i) const { return val_[i]; } 67 | inline const int& row_ptr(int i) const { return rowptr_[i]; } 68 | inline const int& col_ind(int i) const { return colind_[i];} 69 | 70 | inline int dim1() const {return dim1_;} 71 | inline int dim2() const {return dim2_;} 72 | int NumNonzeros() const {return val_.dim1();} 73 | 74 | 75 | Sparse_Matrix_CompRow& operator=( 76 | const Sparse_Matrix_CompRow &R); 77 | 78 | 79 | 80 | }; 81 | 82 | /** 83 | Construct a read-only view of existing sparse matrix in 84 | compressed-row storage format. 85 | 86 | @param M the number of rows of sparse matrix 87 | @param N the number of columns of sparse matrix 88 | @param nz the number of nonzeros 89 | @param val a contiguous list of nonzero values 90 | @param r row-pointers: r[i] denotes the begining position of row i 91 | (i.e. the ith row begins at val[row[i]]). 92 | @param c column-indices: c[i] denotes the column location of val[i] 93 | */ 94 | template 95 | Sparse_Matrix_CompRow::Sparse_Matrix_CompRow(int M, int N, int nz, 96 | const T *val, int *r, int *c) : val_(nz,val), 97 | rowptr_(M, r), colind_(nz, c), dim1_(M), dim2_(N) {} 98 | 99 | 100 | } 101 | // namespace TNT 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_stopwatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Mathematical and Computational Sciences Division 4 | * National Institute of Technology, 5 | * Gaithersburg, MD USA 6 | * 7 | * 8 | * This software was developed at the National Institute of Standards and 9 | * Technology (NIST) by employees of the Federal Government in the course 10 | * of their official duties. Pursuant to title 17 Section 105 of the 11 | * United States Code, this software is not subject to copyright protection 12 | * and is in the public domain. NIST assumes no responsibility whatsoever for 13 | * its use by other parties, and makes no guarantees, expressed or implied, 14 | * about its quality, reliability, or any other characteristic. 15 | * 16 | */ 17 | 18 | 19 | 20 | #ifndef STOPWATCH_H 21 | #define STOPWATCH_H 22 | 23 | // for clock() and CLOCKS_PER_SEC 24 | #include 25 | 26 | 27 | namespace TNT 28 | { 29 | 30 | inline static double seconds(void) 31 | { 32 | const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; 33 | return ( (double) clock() ) * secs_per_tick; 34 | } 35 | 36 | class Stopwatch { 37 | private: 38 | int running_; 39 | double start_time_; 40 | double total_; 41 | 42 | public: 43 | inline Stopwatch(); 44 | inline void start(); 45 | inline double stop(); 46 | inline double read(); 47 | inline void resume(); 48 | inline int running(); 49 | }; 50 | 51 | inline Stopwatch::Stopwatch() : running_(0), start_time_(0.0), total_(0.0) {} 52 | 53 | void Stopwatch::start() 54 | { 55 | running_ = 1; 56 | total_ = 0.0; 57 | start_time_ = seconds(); 58 | } 59 | 60 | double Stopwatch::stop() 61 | { 62 | if (running_) 63 | { 64 | total_ += (seconds() - start_time_); 65 | running_ = 0; 66 | } 67 | return total_; 68 | } 69 | 70 | inline void Stopwatch::resume() 71 | { 72 | if (!running_) 73 | { 74 | start_time_ = seconds(); 75 | running_ = 1; 76 | } 77 | } 78 | 79 | 80 | inline double Stopwatch::read() 81 | { 82 | if (running_) 83 | { 84 | stop(); 85 | resume(); 86 | } 87 | return total_; 88 | } 89 | 90 | 91 | } /* TNT namespace */ 92 | #endif 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_subscript.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_SUBSCRPT_H 22 | #define TNT_SUBSCRPT_H 23 | 24 | 25 | //--------------------------------------------------------------------- 26 | // This definition describes the default TNT data type used for 27 | // indexing into TNT matrices and vectors. The data type should 28 | // be wide enough to index into large arrays. It defaults to an 29 | // "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE, 30 | // e.g. 31 | // 32 | // c++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ... 33 | // 34 | //--------------------------------------------------------------------- 35 | // 36 | 37 | #ifndef TNT_SUBSCRIPT_TYPE 38 | #define TNT_SUBSCRIPT_TYPE int 39 | #endif 40 | 41 | namespace TNT 42 | { 43 | typedef TNT_SUBSCRIPT_TYPE Subscript; 44 | } /* namespace TNT */ 45 | 46 | 47 | // () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the 48 | // first elements. This offset is left as a macro for future 49 | // purposes, but should not be changed in the current release. 50 | // 51 | // 52 | #define TNT_BASE_OFFSET (1) 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /platforms/reference/src/SimTKReference/tnt_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | #ifndef TNT_VERSION_H 21 | #define TNT_VERSION_H 22 | 23 | 24 | //--------------------------------------------------------------------- 25 | // current version 26 | //--------------------------------------------------------------------- 27 | 28 | 29 | #define TNT_MAJOR_VERSION '1' 30 | #define TNT_MINOR_VERSION '2' 31 | #define TNT_SUBMINOR_VERSION '6' 32 | #define TNT_VERSION_STRING "1.2.6" 33 | 34 | 35 | 36 | 37 | 38 | #endif 39 | // TNT_VERSION_H 40 | -------------------------------------------------------------------------------- /platforms/reference/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Testing 3 | # 4 | 5 | ENABLE_TESTING() 6 | 7 | # Automatically create tests using files named "Test*.cpp" 8 | FILE(GLOB TEST_PROGS "*Test*.cpp") 9 | FOREACH(TEST_PROG ${TEST_PROGS}) 10 | GET_FILENAME_COMPONENT(TEST_ROOT ${TEST_PROG} NAME_WE) 11 | 12 | # Link with shared library 13 | ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG}) 14 | TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_MPID_TARGET} ${SHARED_TARGET}) 15 | SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") 16 | ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT}) 17 | 18 | ENDFOREACH(TEST_PROG ${TEST_PROGS}) 19 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(WRAP_FILE MPIDPluginWrapper.cpp) 2 | set(MODULE_NAME mpidplugin) 3 | 4 | # Execute SWIG to generate source code for the Python module. 5 | 6 | add_custom_command( 7 | OUTPUT "${WRAP_FILE}" 8 | COMMAND "${SWIG_EXECUTABLE}" 9 | -python -c++ 10 | -o "${WRAP_FILE}" 11 | "-I${OPENMM_DIR}/include" 12 | "${CMAKE_CURRENT_SOURCE_DIR}/mpidplugin.i" 13 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/mpidplugin.i" 14 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 15 | ) 16 | 17 | # Compile the Python module. 18 | 19 | add_custom_target(PythonInstall DEPENDS "${WRAP_FILE}") 20 | set(MPIDPLUGIN_HEADER_DIR "${CMAKE_SOURCE_DIR}/openmmapi/include") 21 | set(MPIDPLUGIN_HEADER_DIR "${CMAKE_SOURCE_DIR}/openmmapi/include/openmm") 22 | set(MPIDPLUGIN_LIBRARY_DIR "${CMAKE_BINARY_DIR}") 23 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py ${CMAKE_CURRENT_BINARY_DIR}/setup.py) 24 | add_custom_command(TARGET PythonInstall 25 | COMMAND "${PYTHON_EXECUTABLE}" setup.py build 26 | COMMAND "${PYTHON_EXECUTABLE}" setup.py install 27 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 28 | ) 29 | 30 | -------------------------------------------------------------------------------- /python/header.i: -------------------------------------------------------------------------------- 1 | 2 | %header %{ 3 | namespace OpenMM { 4 | 5 | PyObject *copyVVec3ToList(std::vector vVec3) { 6 | int i, n; 7 | PyObject *pyList; 8 | 9 | n=vVec3.size(); 10 | pyList=PyList_New(n); 11 | PyObject* mm = PyImport_AddModule("openmm"); 12 | PyObject* vec3 = PyObject_GetAttrString(mm, "Vec3"); 13 | for (i=0; i= 0); 29 | } 30 | return available; 31 | } 32 | 33 | } // namespace OpenMM 34 | %} 35 | -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | import os 4 | import sys 5 | import platform 6 | import numpy 7 | 8 | openmm_dir = '@OPENMM_DIR@' 9 | mpidplugin_header_dir = '@MPIDPLUGIN_HEADER_DIR@' 10 | mpidplugin_library_dir = '@MPIDPLUGIN_LIBRARY_DIR@' 11 | 12 | # setup extra compile and link arguments on Mac 13 | extra_compile_args = [] 14 | extra_link_args = [] 15 | 16 | if platform.system() == 'Darwin': 17 | extra_compile_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7'] 18 | extra_link_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7', '-Wl', '-rpath', openmm_dir+'/lib'] 19 | 20 | extension = Extension(name='_mpidplugin', 21 | sources=['MPIDPluginWrapper.cpp'], 22 | libraries=['OpenMM', 'MPIDPlugin'], 23 | include_dirs=[os.path.join(openmm_dir, 'include'), mpidplugin_header_dir, numpy.get_include()], 24 | library_dirs=[os.path.join(openmm_dir, 'lib'), mpidplugin_library_dir], 25 | extra_compile_args=extra_compile_args, 26 | extra_link_args=extra_link_args 27 | ) 28 | 29 | setup(name='mpidplugin', 30 | version='1.0', 31 | py_modules=['mpidplugin'], 32 | ext_modules=[extension], 33 | ) 34 | -------------------------------------------------------------------------------- /serialization/include/openmm/serialization/MPIDForceProxy.h: -------------------------------------------------------------------------------- 1 | #ifndef OPENMM_MPID_MULTIPOLE_FORCE_PROXY_H_ 2 | #define OPENMM_MPID_MULTIPOLE_FORCE_PROXY_H_ 3 | 4 | /* -------------------------------------------------------------------------- * 5 | * OpenMMMPID * 6 | * -------------------------------------------------------------------------- * 7 | * This is part of the OpenMM molecular simulation toolkit originating from * 8 | * Simbios, the NIH National Center for Physics-Based Simulation of * 9 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 10 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 11 | * * 12 | * Portions copyright (c) 2010 Stanford University and the Authors. * 13 | * Authors: Peter Eastman * 14 | * Contributors: * 15 | * * 16 | * Permission is hereby granted, free of charge, to any person obtaining a * 17 | * copy of this software and associated documentation files (the "Software"), * 18 | * to deal in the Software without restriction, including without limitation * 19 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 20 | * and/or sell copies of the Software, and to permit persons to whom the * 21 | * Software is furnished to do so, subject to the following conditions: * 22 | * * 23 | * The above copyright notice and this permission notice shall be included in * 24 | * all copies or substantial portions of the Software. * 25 | * * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 28 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 29 | * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 30 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 31 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 32 | * USE OR OTHER DEALINGS IN THE SOFTWARE. * 33 | * -------------------------------------------------------------------------- */ 34 | 35 | #include "openmm/internal/windowsExportMPID.h" 36 | #include "openmm/serialization/SerializationProxy.h" 37 | 38 | namespace OpenMM { 39 | 40 | /** 41 | * This is a proxy for serializing MPIDForce objects. 42 | */ 43 | 44 | class OPENMM_EXPORT_MPID MPIDForceProxy : public SerializationProxy { 45 | public: 46 | MPIDForceProxy(); 47 | void serialize(const void* object, SerializationNode& node) const; 48 | void* deserialize(const SerializationNode& node) const; 49 | }; 50 | 51 | } // namespace OpenMM 52 | 53 | #endif /*OPENMM_MPID_MULTIPOLE_FORCE_PROXY_H_*/ 54 | -------------------------------------------------------------------------------- /serialization/src/MPIDSerializationProxyRegistration.cpp: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- * 2 | * OpenMMMPID * 3 | * -------------------------------------------------------------------------- * 4 | * This is part of the OpenMM molecular simulation toolkit originating from * 5 | * Simbios, the NIH National Center for Physics-Based Simulation of * 6 | * Biological Structures at Stanford, funded under the NIH Roadmap for * 7 | * Medical Research, grant U54 GM072970. See https://simtk.org. * 8 | * * 9 | * Portions copyright (c) 2010 Stanford University and the Authors. * 10 | * Authors: Peter Eastman * 11 | * Contributors: * 12 | * * 13 | * Permission is hereby granted, free of charge, to any person obtaining a * 14 | * copy of this software and associated documentation files (the "Software"), * 15 | * to deal in the Software without restriction, including without limitation * 16 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 17 | * and/or sell copies of the Software, and to permit persons to whom the * 18 | * Software is furnished to do so, subject to the following conditions: * 19 | * * 20 | * The above copyright notice and this permission notice shall be included in * 21 | * all copies or substantial portions of the Software. * 22 | * * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 24 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 25 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 26 | * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 27 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 28 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 29 | * USE OR OTHER DEALINGS IN THE SOFTWARE. * 30 | * -------------------------------------------------------------------------- */ 31 | 32 | #ifdef WIN32 33 | #include 34 | #include 35 | #else 36 | #include 37 | #include 38 | #include 39 | #endif 40 | 41 | #include "openmm/OpenMMException.h" 42 | 43 | #include "openmm/MPIDForce.h" 44 | 45 | #include "openmm/serialization/SerializationProxy.h" 46 | 47 | #include "openmm/serialization/MPIDForceProxy.h" 48 | 49 | #if defined(WIN32) 50 | #include 51 | extern "C" OPENMM_EXPORT_MPID void registerMPIDSerializationProxies(); 52 | BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { 53 | if (ul_reason_for_call == DLL_PROCESS_ATTACH) 54 | registerMPIDSerializationProxies(); 55 | return TRUE; 56 | } 57 | #else 58 | extern "C" void __attribute__((constructor)) registerMPIDSerializationProxies(); 59 | #endif 60 | 61 | using namespace OpenMM; 62 | 63 | extern "C" OPENMM_EXPORT_MPID void registerMPIDSerializationProxies() { 64 | SerializationProxy::registerProxy(typeid(MPIDForce), new MPIDForceProxy()); 65 | } 66 | -------------------------------------------------------------------------------- /serialization/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Testing 3 | # 4 | 5 | ENABLE_TESTING() 6 | 7 | # Automatically create tests using files named "Test*.cpp" 8 | FILE(GLOB TEST_PROGS "*Test*.cpp") 9 | FOREACH(TEST_PROG ${TEST_PROGS}) 10 | GET_FILENAME_COMPONENT(TEST_ROOT ${TEST_PROG} NAME_WE) 11 | 12 | # All tests use shared libraries 13 | ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG}) 14 | TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_MPID_TARGET} OpenMM) 15 | SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") 16 | ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT}) 17 | 18 | ENDFOREACH(TEST_PROG ${TEST_PROGS}) 19 | --------------------------------------------------------------------------------