Add initial nblib public API
authorJoe Jordan <ejjordan12@gmail.com>
Mon, 28 Sep 2020 10:35:59 +0000 (10:35 +0000)
committerJoe Jordan <ejjordan12@gmail.com>
Mon, 28 Sep 2020 10:35:59 +0000 (10:35 +0000)
27 files changed:
api/CMakeLists.txt
api/nblib/CMakeLists.txt [new file with mode: 0644]
api/nblib/basicdefinitions.h [new file with mode: 0644]
api/nblib/box.cpp [new file with mode: 0644]
api/nblib/box.h [new file with mode: 0644]
api/nblib/exception.h [new file with mode: 0644]
api/nblib/forcecalculator.h [new file with mode: 0644]
api/nblib/integrator.h [new file with mode: 0644]
api/nblib/interactions.h [new file with mode: 0644]
api/nblib/kerneloptions.h [new file with mode: 0644]
api/nblib/molecules.h [new file with mode: 0644]
api/nblib/nblib.h [new file with mode: 0644]
api/nblib/particletype.h [new file with mode: 0644]
api/nblib/simulationstate.h [new file with mode: 0644]
api/nblib/tests/CMakeLists.txt [new file with mode: 0644]
api/nblib/tests/box.cpp [new file with mode: 0644]
api/nblib/tests/testhelpers.cpp [new file with mode: 0644]
api/nblib/tests/testhelpers.h [new file with mode: 0644]
api/nblib/topology.h [new file with mode: 0644]
api/nblib/topologyhelpers.h [new file with mode: 0644]
api/nblib/util/CMakeLists.txt [new file with mode: 0644]
api/nblib/util/user.h [new file with mode: 0644]
api/nblib/vector.h [new file with mode: 0644]
docs/CMakeLists.txt
docs/index.rst
docs/nblib/guide-to-writing-MD-programs.rst [new file with mode: 0644]
docs/nblib/index.rst [new file with mode: 0644]

index b9e91082db09e138fff306a5f674c3e64308433b..327282eea8f36ac6cabe0fd9a26c982d7c65d534 100644 (file)
@@ -46,3 +46,9 @@ option(GMXAPI "Install GROMACS API." ${_GMXAPI_DEFAULT})
 if (GMXAPI)
     add_subdirectory(gmxapi)
 endif()
+
+add_subdirectory(nblib)
+if(GMX_INSTALL_NBLIB_API)
+    install(FILES
+            DESTINATION include/nblib)
+endif()
diff --git a/api/nblib/CMakeLists.txt b/api/nblib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d92950b
--- /dev/null
@@ -0,0 +1,133 @@
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2020, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+#
+# \author Victor Holanda <victor.holanda@cscs.ch>
+# \author Joe Jordan <ejjordan@kth.se>
+# \author Prashanth Kanduri <kanduri@cscs.ch>
+# \author Sebastian Keller <keller@cscs.ch>
+#
+
+# The following are copied directly from src/CMakeLists.txt
+set(IGNORED_CLANG_ALL_WARNINGS
+        "-Wno-c++98-compat -Wno-c++98-compat-pedantic" #No intention of C++98 compability
+        "-Wno-source-uses-openmp" #Don't warn for no-omp build
+        "-Wno-c++17-extensions"   #Allowed in attributes (compilers are required to ignore unknown attributes)
+        "-Wno-documentation-unknown-command" #Custom commands are used
+        "-Wno-covered-switch-default" #GCC gives maybe-uninitialized without default label and checks for illegal enum values.
+        "-Wno-switch-enum" # default statement for enum is OK
+
+        # We need to use macros like
+        # GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR. Those will look strange
+        # if they don't have a semicolon after them, and might confuse
+        # tools like IDEs also.
+        "-Wno-extra-semi-stmt"
+
+        #Following ones are undecided/TODO
+        "-Wno-disabled-macro-expansion"
+        "-Wno-cast-align"
+        "-Wno-reserved-id-macro"
+        "-Wno-global-constructors"
+        "-Wno-exit-time-destructors"
+        "-Wno-unused-macros"
+        "-Wno-weak-vtables"
+        "-Wno-conditional-uninitialized"
+        "-Wno-format-nonliteral"
+        "-Wno-shadow"
+        "-Wno-cast-qual"
+        "-Wno-documentation"
+        "-Wno-used-but-marked-unused"
+        "-Wno-padded"
+        "-Wno-float-equal"
+        "-Wno-old-style-cast"
+        "-Wno-conversion"
+        "-Wno-double-promotion")
+string(REPLACE " " ";" IGNORED_CLANG_ALL_WARNINGS "${IGNORED_CLANG_ALL_WARNINGS}")
+
+set(TESTUTILS_DIR ${PROJECT_SOURCE_DIR}/src/testutils)
+include(${PROJECT_SOURCE_DIR}/src/testutils/TestMacros.cmake)
+
+# this allows all nblib tests to be run with "make check-nblib"
+add_custom_target(check-nblib
+        COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R NbLib
+        COMMENT "Running nblib tests"
+        USES_TERMINAL VERBATIM)
+
+add_library(nblib SHARED "")
+
+target_sources(nblib
+        PRIVATE
+        box.cpp
+        )
+
+set_target_properties(nblib
+        PROPERTIES
+        LINKER_LANGUAGE CXX
+        OUTPUT_NAME "nblib"
+        )
+
+target_link_libraries(nblib PRIVATE libgromacs)
+target_include_directories(nblib PRIVATE ${PROJECT_SOURCE_DIR}/api)
+include_directories(BEFORE ${CMAKE_SOURCE_DIR}/api)
+
+install(TARGETS nblib
+        EXPORT nblib
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        INCLUDES DESTINATION include
+        )
+
+if(GMX_INSTALL_NBLIB_API)
+    install(FILES
+            basicdefinitions.h
+            box.h
+            exception.h
+            forcecalculator.h
+            integrator.h
+            interactions.h
+            molecules.h
+            kerneloptions.h
+            nblib.h
+            particletype.h
+            simulationstate.h
+            topology.h
+            topologyhelpers.h
+            DESTINATION include/nblib)
+endif()
+
+add_subdirectory(util)
+
+if(BUILD_TESTING)
+    add_subdirectory(tests)
+endif()
diff --git a/api/nblib/basicdefinitions.h b/api/nblib/basicdefinitions.h
new file mode 100644 (file)
index 0000000..41dabd3
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements some definitions that are identical to those of gromacs
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_BASICDEFINITIONS_H
+#define NBLIB_BASICDEFINITIONS_H
+
+#include <cmath>
+
+// from utility/real.h
+#if GMX_DOUBLE
+#    ifndef HAVE_REAL
+typedef double real;
+#        define HAVE_REAL
+#    endif
+#else /* GMX_DOUBLE */
+#    ifndef HAVE_REAL
+typedef float real;
+#        define HAVE_REAL
+#    endif
+#endif /* GMX_DOUBLE */
+
+namespace nblib
+{
+
+namespace detail
+{
+// from math/units.h
+constexpr const float  KILO      = 1e3;             /* Thousand        */
+constexpr const double NANO      = 1e-9;            /* A Number        */
+constexpr const double E_CHARGE  = 1.602176634e-19; /* Exact definition, Coulomb NIST 2018 CODATA */
+constexpr const double BOLTZMANN = 1.380649e-23;    /* (J/K, Exact definition, NIST 2018 CODATA */
+constexpr const double AVOGADRO  = 6.02214076e23;   /* 1/mol, Exact definition, NIST 2018 CODATA */
+constexpr const double RGAS      = (BOLTZMANN * AVOGADRO); /* (J/(mol K))  */
+constexpr const double EPSILON0_SI = 8.8541878128e-12;     /* F/m,  NIST 2018 CODATA */
+constexpr const double EPSILON0 = ((EPSILON0_SI * NANO * KILO) / (E_CHARGE * E_CHARGE * AVOGADRO));
+
+// from pbc/ishift.h
+constexpr const int D_BOX_Z = 1;
+constexpr const int D_BOX_Y = 1;
+constexpr const int D_BOX_X = 2;
+constexpr const int N_BOX_Z = (2 * D_BOX_Z + 1);
+constexpr const int N_BOX_Y = (2 * D_BOX_Y + 1);
+constexpr const int N_BOX_X = (2 * D_BOX_X + 1);
+constexpr const int N_IVEC  = (N_BOX_Z * N_BOX_Y * N_BOX_X);
+} // namespace detail
+
+//! Needed for generating Bolzmann velocity distribution (kJ/(mol K))
+constexpr const real BOLTZ = (detail::RGAS / detail::KILO); /*  */
+
+//! Charge multiplication factor for Coulomb interactions
+constexpr const real ONE_4PI_EPS0 = (1.0 / (4.0 * M_PI * detail::EPSILON0));
+
+//! Conversion factor from degrees to radians
+constexpr const real DEG2RAD = M_PI / 180.0;
+
+//! The number of shift vectors needed for pbc
+constexpr const int numShiftVectors = detail::N_IVEC;
+
+// from math/vectypes.h
+constexpr const int dimX = 0; /* Defines for indexing in vectors */
+constexpr const int dimY = 1;
+constexpr const int dimZ = 2;
+
+constexpr const int dimSize = 3;
+typedef real        rvec[dimSize];
+typedef real        matrix[dimSize][dimSize];
+} // namespace nblib
+
+
+#endif // NBLIB_BASICDEFINITIONS_H
diff --git a/api/nblib/box.cpp b/api/nblib/box.cpp
new file mode 100644 (file)
index 0000000..8d3c377
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements nblib simulation box
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#include <cmath>
+
+#include "nblib/box.h"
+#include "nblib/exception.h"
+
+namespace nblib
+{
+
+Box::Box(real l) : Box(l, l, l) {}
+
+Box::Box(real x, real y, real z) : legacyMatrix_{ 0 }
+{
+    if (std::isnan(x) || std::isinf(x) || std::isnan(y) || std::isinf(y) || std::isnan(z) || std::isinf(z))
+    {
+        throw InputException("Cannot have NaN or Inf box length.");
+    }
+
+    legacyMatrix_[dimX][dimX] = x;
+    legacyMatrix_[dimY][dimY] = y;
+    legacyMatrix_[dimZ][dimZ] = z;
+}
+
+} // namespace nblib
diff --git a/api/nblib/box.h b/api/nblib/box.h
new file mode 100644 (file)
index 0000000..c1aaead
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib simulation box
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_BOX_H
+#define NBLIB_BOX_H
+
+#include "nblib/basicdefinitions.h"
+
+namespace nblib
+{
+
+/*! \brief Box specifies the size of periodic simulation systems
+ *
+ * \inpublicapi
+ * \ingroup nblib
+ *
+ * Currently only cubic and rectangular boxes are supported.
+ *
+ */
+class Box final
+{
+public:
+    using LegacyMatrix = matrix;
+
+    //! Construct a cubic box.
+    explicit Box(real l);
+
+    //! Construct a rectangular box.
+    Box(real x, real y, real z);
+
+    //! Return the full matrix that specifies the box. Used for gromacs setup code.
+    [[nodiscard]] LegacyMatrix const& legacyMatrix() const { return legacyMatrix_; }
+
+private:
+    LegacyMatrix legacyMatrix_;
+};
+
+} // namespace nblib
+#endif // NBLIB_BOX_H
diff --git a/api/nblib/exception.h b/api/nblib/exception.h
new file mode 100644 (file)
index 0000000..c83a53b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib exception class
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_EXCEPTION_H
+#define NBLIB_EXCEPTION_H
+
+#include <exception>
+#include <string>
+
+namespace nblib
+{
+
+/*! \brief Base nblib exception class
+ *
+ * All nblib exceptions derive from this class and simply forward their message. This allows
+ * exceptions to be handled uniformly across different exception types.
+ */
+class NbLibException : public std::exception
+{
+public:
+    [[maybe_unused]] explicit NbLibException(const std::string& message) :
+        message_("NbLib Exception: " + message)
+    {
+    }
+
+    //! Overrides the what() in std::exception
+    [[nodiscard]] const char* what() const noexcept override { return message_.c_str(); }
+
+    //! Convenience call in case a string is wanted instead of a const char*
+    [[nodiscard]] const std::string& reason() const& { return message_; }
+
+private:
+    std::string message_;
+};
+
+/*! \brief The exception type for user input errors
+ *
+ * The message should give users some hint as to how to remedy the error.
+ */
+class InputException final : NbLibException
+{
+public:
+    using NbLibException::NbLibException;
+};
+
+} // namespace nblib
+#endif // NBLIB_EXCEPTION_H
diff --git a/api/nblib/forcecalculator.h b/api/nblib/forcecalculator.h
new file mode 100644 (file)
index 0000000..7083da5
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib ForceCalculator
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_FORCECALCULATOR_H
+#define NBLIB_FORCECALCULATOR_H
+
+#include "nblib/interactions.h"
+#include "nblib/kerneloptions.h"
+#include "nblib/simulationstate.h"
+
+namespace gmx
+{
+template<typename T>
+class ArrayRef;
+} // namespace gmx
+
+namespace nblib
+{
+class NbvSetupUtil;
+class GmxForceCalculator;
+
+/*! \brief Setups up and computes forces using gromacs backend.
+ *
+ * The ForceCalculator uses the data in the SimulationState and NBKernelOptions to opaquely
+ * construct all gromacs data structures needed to perform nonbonded force calculations. It is
+ * costly to create this object since much of the SimulationState and NBKernelOptions has to be
+ * passed to the gromacs backend. However, once constructed, compute can be called repeatedly only
+ * paying the cost of the actual nonbonded force calculation. Repeated calls to compute on the same
+ * coordinated will always return the same forces (within precision), so the user must update the
+ * positions using the forces generated here to advance a simulation. If the coordinates move
+ * sufficiently far from their positions at construction time, the efficiency of the calculation
+ * will suffer. To alleviate this, the user can call updatePairList.
+ *
+ */
+class ForceCalculator final
+{
+public:
+    ForceCalculator(const SimulationState& system, const NBKernelOptions& options);
+
+    ~ForceCalculator();
+
+    /*! \brief Dispatch the nonbonded force kernels and reduce the forces
+     *
+     * This function zeroes out all values in the passed in forces buffer, so it can be regarded as
+     * an output only param.
+     *
+     * \param[in] coordinates to be used for the force calculation
+     * \param[out] forces buffer to store the output forces
+     */
+    void compute(gmx::ArrayRef<const Vec3> coordinates, gmx::ArrayRef<Vec3> forces);
+
+    /*! \brief Puts particles on a grid based on bounds specified by the box
+     *
+     * As compute is called repeatedly, the particles drift apart and the force computation becomes
+     * progressively less efficient. Calling this function recomputes the particle-particle pair
+     * lists so that computation can proceed efficiently. Should be called around every 100 steps.
+     *
+     * \param particleInfoAllVdW The types of the particles to be placed on grids
+     * \param coordinates The coordinates to be placed on grids
+     * \param[in] box The system simulation box
+     */
+    void updatePairList(gmx::ArrayRef<const int> particleInfoAllVdW,
+                        gmx::ArrayRef<Vec3>      coordinates,
+                        const Box&               box);
+
+private:
+    //! GROMACS force calculator to compute forces
+    std::unique_ptr<GmxForceCalculator> gmxForceCalculator_;
+};
+
+} // namespace nblib
+
+#endif // NBLIB_FORCECALCULATOR_H
diff --git a/api/nblib/integrator.h b/api/nblib/integrator.h
new file mode 100644 (file)
index 0000000..f72d6b4
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib integrator
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_INTEGRATOR_H
+#define NBLIB_INTEGRATOR_H
+
+#include <vector>
+
+#include "nblib/box.h"
+#include "nblib/vector.h"
+
+namespace gmx
+{
+template<typename T>
+class ArrayRef;
+} // namespace gmx
+
+namespace nblib
+{
+
+class Topology;
+
+/*! \brief Simple integrator
+ *
+ */
+class LeapFrog final
+{
+public:
+    /*! \brief Constructor.
+     *
+     * \param[in] topology  Topology object to build list of inverse masses.
+     * \param[in] box       Box object for ensuring that coordinates remain within bounds
+     */
+    LeapFrog(const Topology& topology, const Box& box);
+
+    /*! \brief Integrate
+     *
+     * Integrates the equation of motion using Leap-Frog algorithm.
+     * Updates coordinates and velocities.
+     *
+     * \param[in]  dt          Timestep.
+     * \param[out] coordinates Coordinate array that would be modified in-place.
+     * \param[out] velocities  Velocity array that would be modified in-place.
+     * \param[in]  forces      Force array to be read.
+     *
+     */
+    void integrate(real                      dt,
+                   gmx::ArrayRef<Vec3>       coordinates,
+                   gmx::ArrayRef<Vec3>       velocities,
+                   gmx::ArrayRef<const Vec3> forces);
+
+private:
+    //! 1/mass for all atoms
+    std::vector<real> inverseMasses_;
+    //! Box for PBC conformity
+    Box box_;
+};
+
+} // namespace nblib
+
+#endif // NBLIB_INTEGRATOR_H
diff --git a/api/nblib/interactions.h b/api/nblib/interactions.h
new file mode 100644 (file)
index 0000000..7a3e245
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib particle-types interactions
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_INTERACTIONS_H
+#define NBLIB_INTERACTIONS_H
+
+#include <map>
+#include <tuple>
+#include <unordered_map>
+
+#include "nblib/kerneloptions.h"
+#include "nblib/particletype.h"
+#include "nblib/util/user.h"
+
+namespace nblib
+{
+
+//! Shorthand for a map used for looking up non-bonded parameters using particle types
+//! Named type for the C6 parameter in the Lennard-Jones potential
+using C6 = StrongType<real, struct C6Parameter>;
+//! Named type for the C12 parameter in the Lennard-Jones potential
+using C12 = StrongType<real, struct C12Parameter>;
+
+using NonBondedInteractionMapImpl =
+        std::map<std::tuple<ParticleTypeName, ParticleTypeName>, std::tuple<C6, C12>>;
+
+//! Map used for looking up non-bonded parameters using particle types
+class NonBondedInteractionMap final
+{
+private:
+    using NamePairTuple   = std::tuple<ParticleTypeName, ParticleTypeName>;
+    using ComboParameters = std::tuple<C6, C12>;
+    using InteractionMap  = std::map<NamePairTuple, ComboParameters>;
+    InteractionMap interactionMap_;
+
+public:
+    void   setInteractions(const ParticleTypeName&, const ParticleTypeName&, const C6, const C12);
+    size_t count(const NamePairTuple&);
+
+    [[nodiscard]] C6  getC6(const ParticleTypeName&, const ParticleTypeName&) const;
+    [[nodiscard]] C12 getC12(const ParticleTypeName&, const ParticleTypeName&) const;
+
+    InteractionMap::iterator begin() { return interactionMap_.begin(); }
+    InteractionMap::iterator end() { return interactionMap_.end(); }
+};
+
+/*! \brief Non-Bonded Interactions between Particle Types
+ *
+ * \inpublicapi
+ * \ingroup nblib
+ *
+ * A class to hold a mapping between pairs of particle types and the non-bonded
+ * interactions between them. One may add the non-bonded parameters, namely the
+ * C6/C12 params for each particle type individually and construct a pair-wise
+ * mapping using combination rules or manually specify the parameters between
+ * a specific pair.
+ *
+ */
+class ParticleTypesInteractions final
+{
+public:
+    //! Initialized with the default geometric combination rule
+    explicit ParticleTypesInteractions(CombinationRule = CombinationRule::Geometric);
+
+    //! Specify non-bonded params of a particle type
+    ParticleTypesInteractions& add(const ParticleTypeName& particleTypeName, C6 c6, C12 c12);
+
+    //! Specify the non-bonded params of a specific pair of particle types
+    ParticleTypesInteractions& add(const ParticleTypeName& particleTypeName1,
+                                   const ParticleTypeName& particleTypeName2,
+                                   C6                      c6,
+                                   C12                     c12);
+
+    //! Generate table based on the parameters stored
+    [[nodiscard]] NonBondedInteractionMap generateTable() const;
+
+    //! Get combination rule enabled in this object
+    [[nodiscard]] CombinationRule getCombinationRule() const;
+
+    //! Merge with the information stored in another ParticleTypesInteractions object
+    void merge(const ParticleTypesInteractions&);
+
+private:
+    CombinationRule combinationRule_;
+
+    std::map<ParticleTypeName, std::tuple<C6, C12>> singleParticleInteractionsMap_;
+    std::map<std::tuple<ParticleTypeName, ParticleTypeName>, std::tuple<C6, C12>> twoParticlesInteractionsMap_;
+};
+
+} // namespace nblib
+#endif // NBLIB_INTERACTIONS_H
diff --git a/api/nblib/kerneloptions.h b/api/nblib/kerneloptions.h
new file mode 100644 (file)
index 0000000..dfd72e7
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib kernel setup options
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_KERNELOPTIONS_H
+#define NBLIB_KERNELOPTIONS_H
+
+#include <memory>
+
+#include "nblib/basicdefinitions.h"
+
+namespace nblib
+{
+
+//! Enum for selecting the SIMD kernel type
+enum class SimdKernels : int
+{
+    SimdAuto,
+    SimdNo,
+    Simd4XM,
+    Simd2XMM,
+    Count
+};
+
+//! Enum for selecting the combination rule
+enum class CombinationRule : int
+{
+    Geometric,
+    LorentzBerthelot,
+    None,
+    Count
+};
+
+//! Enum for selecting coulomb type
+enum class CoulombType : int
+{
+    Pme,
+    Cutoff,
+    ReactionField,
+    Count
+};
+
+/*! \internal \brief
+ * The options for the nonbonded kernel caller
+ */
+struct NBKernelOptions final
+{
+    //! Whether to use a GPU, currently GPUs are not supported
+    bool useGpu = false;
+    //! The number of OpenMP threads to use
+    int numOpenMPThreads = 1;
+    //! The SIMD type for the kernel
+    SimdKernels nbnxmSimd = SimdKernels::SimdAuto;
+    //! The LJ combination rule
+    CombinationRule ljCombinationRule = CombinationRule::Geometric;
+    //! Use i-cluster half-LJ optimization for clusters with <= half LJ
+    bool useHalfLJOptimization = false;
+    //! The pairlist and interaction cut-off
+    real pairlistCutoff = 1.0;
+    //! Whether to compute energies (shift forces for virial are always computed on CPU)
+    bool computeVirialAndEnergy = false;
+    //! The Coulomb interaction function
+    CoulombType coulombType = CoulombType::Pme;
+    //! Whether to use tabulated PME grid correction instead of analytical, not applicable with simd=no
+    bool useTabulatedEwaldCorr = false;
+    //! The number of iterations for each kernel
+    int numIterations = 100;
+    //! Print cycles/pair instead of pairs/cycle
+    bool cyclesPerPair = false;
+    //! The time step
+    real timestep = 0.001;
+};
+
+} // namespace nblib
+
+#endif // NBLIB_KERNELOPTIONS_H
diff --git a/api/nblib/molecules.h b/api/nblib/molecules.h
new file mode 100644 (file)
index 0000000..afcae8c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief
+ * Implements nblib Molecule
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ *
+ * \inpublicapi
+ * \ingroup nblib
+ */
+#ifndef NBLIB_MOLECULES_H
+#define NBLIB_MOLECULES_H
+
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+#include "nblib/particletype.h"
+
+namespace nblib
+{
+//! Named type for unique identifier for a particle in a molecule
+using ParticleName = StrongType<std::string, struct ParticleNameParameter>;
+
+//! Named type for charges on a particle within a molecule
+using Charge = StrongType<real, struct ChargeParameter>;
+
+//! Named type for residue name used to diffentiate between sections of a molecule
+using ResidueName = StrongType<std::string, struct ResidueNameParameter>;
+
+//! Named type for the name of a molecule
+using MoleculeName = StrongType<std::string, struct MoleculeNameParameter>;
+
+struct ParticleData
+{
+    std::string particleName_;
+    std::string residueName_;
+    std::string particleTypeName_;
+    real        charge_;
+};
+
+class Molecule final
+{
+public:
+    explicit Molecule(MoleculeName moleculeName);
+
+    //! Add a particle to the molecule with full specification of parameters.
+    Molecule& addParticle(const ParticleName& particleName,
+                          const ResidueName&  residueName,
+                          const Charge&       charge,
+                          ParticleType const& particleType);
+
+    //! Add a particle to the molecule with implicit charge of 0
+    Molecule& addParticle(const ParticleName& particleName,
+                          const ResidueName&  residueName,
+                          ParticleType const& particleType);
+
+    //! Add a particle to the molecule with residueName set using particleName
+    Molecule& addParticle(const ParticleName& particleName, const Charge& charge, ParticleType const& particleType);
+
+    //! Add a particle to the molecule with residueName set using particleName with implicit charge of 0
+    Molecule& addParticle(const ParticleName& particleName, ParticleType const& particleType);
+
+    // TODO: add exclusions based on the unique ID given to the particle of the molecule
+    void addExclusion(int particleIndex, int particleIndexToExclude);
+
+    //! Specify an exclusion with particle and residue names that have been added to molecule
+    void addExclusion(std::tuple<std::string, std::string> particle,
+                      std::tuple<std::string, std::string> particleToExclude);
+
+    //! Specify an exclusion with particle names that have been added to molecule
+    void addExclusion(const std::string& particleName, const std::string& particleNameToExclude);
+
+    //! The number of molecules
+    int numParticlesInMolecule() const;
+
+    //! Return the ParticleType data for a specific particle name that has been added to the molecule
+    const ParticleType& at(const std::string& particlesTypeName) const;
+
+    //! Convert exclusions given by name to indices and unify with exclusions given by indices
+    //! returns a sorted vector containing no duplicates of particles to exclude by indices
+    std::vector<std::tuple<int, int>> getExclusions() const;
+
+    //! Return name of ith particle
+    ParticleName particleName(int i) const;
+
+    //! Return name of ith residue
+    ResidueName residueName(int i) const;
+
+    //! Return array of data structs on particle types
+    std::vector<ParticleData> particleData() const;
+
+    //! Return map of particle types and their names
+    std::unordered_map<std::string, ParticleType> particleTypesMap() const;
+
+    //! The molecule name
+    MoleculeName name() const;
+
+private:
+    //! Name of the molecule
+    MoleculeName name_;
+
+    //! one entry per particle in molecule
+    std::vector<ParticleData> particles_;
+
+    //! collection of distinct particle types in molecule
+    std::unordered_map<std::string, ParticleType> particleTypes_;
+
+    //! Used for calculated exclusions based on particle indices in molecule
+    std::vector<std::tuple<int, int>> exclusions_;
+
+    //! we cannot efficiently compute indices during the build-phase
+    //! so we delay the conversion until TopologyBuilder requests it
+    std::vector<std::tuple<std::string, std::string, std::string, std::string>> exclusionsByName_;
+};
+
+} // namespace nblib
+#endif // NBLIB_MOLECULES_H
diff --git a/api/nblib/nblib.h b/api/nblib/nblib.h
new file mode 100644 (file)
index 0000000..55c510a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Aggregates nblib public API headers
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_HEADERS_H
+#define NBLIB_HEADERS_H
+
+#include "nblib/basicdefinitions.h"
+#include "nblib/box.h"
+#include "nblib/forcecalculator.h"
+#include "nblib/integrator.h"
+#include "nblib/interactions.h"
+#include "nblib/kerneloptions.h"
+#include "nblib/molecules.h"
+#include "nblib/particletype.h"
+#include "nblib/simulationstate.h"
+#include "nblib/topology.h"
+#include "nblib/topologyhelpers.h"
+#include "nblib/util/user.h"
+
+#endif // NBLIB_HEADERS_H
diff --git a/api/nblib/particletype.h b/api/nblib/particletype.h
new file mode 100644 (file)
index 0000000..432bdb4
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief
+ * Declares nblib ParticleTypes
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ *
+ * \inpublicapi
+ * \ingroup nblib
+ */
+#ifndef NBLIB_PARTICLETYPE_H
+#define NBLIB_PARTICLETYPE_H
+
+#include <string>
+
+#include "nblib/util/user.h"
+
+namespace nblib
+{
+class TopologyBuilder;
+
+//! Named type for particle type name
+using ParticleTypeName = StrongType<std::string, struct ParticleTypeNameParameter>;
+//! Named type for particle mass
+using Mass = StrongType<real, struct MassParameter>;
+
+/*! \brief Class that represents the particle type.
+ *
+ * The particle type is used in lookup tables for masses, non-bonded parameters, etc.
+ * Every particle has to assigned an atom type.
+ */
+class ParticleType final
+{
+public:
+    /*! \brief Constructor with explicit name and mass specification.
+     *
+     * \param[in] name The unique name to reference the particle type.
+     * \param[in] mass The mass of the particle of this type.
+     */
+    ParticleType(ParticleTypeName name, Mass mass);
+
+    //! Get the type name
+    [[nodiscard]] ParticleTypeName name() const;
+
+    //! Get the mass
+    [[nodiscard]] Mass mass() const;
+
+private:
+    //! The name
+    ParticleTypeName name_;
+    //! The mass
+    Mass mass_;
+};
+
+/*! \brief Comparison operator
+ *
+ * \param[in] a First type.
+ * \param[in] b Second type.
+ * \returns If the types are identical.
+ */
+bool operator==(const ParticleType& a, const ParticleType& b);
+
+} // namespace nblib
+#endif // NBLIB_PARTICLETYPE_H
diff --git a/api/nblib/simulationstate.h b/api/nblib/simulationstate.h
new file mode 100644 (file)
index 0000000..db93eb5
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib SimulationState
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_SIMULATIONSTATE_H
+#define NBLIB_SIMULATIONSTATE_H
+
+#include <memory>
+#include <vector>
+
+#include "nblib/box.h"
+#include "nblib/topology.h"
+
+namespace nblib
+{
+
+/*! \libinternal
+ * \ingroup nblib
+ * \brief Simulation State
+ *
+ * Simulation state description that serves as a snapshot of the system
+ * being analysed. Needed to init an MD program. Allows hot-starting simulations.
+ */
+
+class SimulationState final
+{
+public:
+    //! Constructor
+    SimulationState(const std::vector<Vec3>& coordinates,
+                    const std::vector<Vec3>& velocities,
+                    const std::vector<Vec3>& forces,
+                    Box                      box,
+                    Topology                 topology);
+
+    //! Returns topology of the current state
+    const Topology& topology() const;
+
+    //! Returns the box
+    Box box() const;
+
+    //! Returns a reference to a (modifiable) vector of particle coordinates
+    std::vector<Vec3>& coordinates();
+
+    //! Returns a read-only vector of particle coordinates
+    const std::vector<Vec3>& coordinates() const;
+
+    //! Returns a reference to a (modifiable) vector of particle velocities
+    std::vector<Vec3>& velocities();
+
+    //! Returns a reference to a (modifiable) vector of forces
+    std::vector<Vec3>& forces();
+
+private:
+    class Impl;
+    std::shared_ptr<SimulationState::Impl> simulationStatePtr_;
+};
+
+} // namespace nblib
+
+#endif // NBLIB_SIMULATIONSTATE_H
diff --git a/api/nblib/tests/CMakeLists.txt b/api/nblib/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7646a52
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2020, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+#
+# \author Victor Holanda <victor.holanda@cscs.ch>
+# \author Joe Jordan <ejjordan@kth.se>
+# \author Prashanth Kanduri <kanduri@cscs.ch>
+# \author Sebastian Keller <keller@cscs.ch>
+#
+
+# Make a static library for test infrastructure code that we re-use
+# in multiple test executables across the repository.
+gmx_add_unit_test_library(nblib_test_infrastructure
+        testhelpers.cpp
+        )
+target_include_directories(nblib_test_infrastructure PRIVATE ${PROJECT_SOURCE_DIR}/api)
+target_include_directories(nblib_test_infrastructure SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/src/external)
+
+
+set(testname "NbLibSetupTests")
+set(exename "nblib-setup-test")
+
+gmx_add_gtest_executable(
+    ${exename}
+    CPP_SOURCE_FILES
+    # files with code for tests
+    box.cpp
+    )
+target_link_libraries(${exename} PRIVATE nblib_test_infrastructure nblib)
+target_include_directories(${exename} PRIVATE ${PROJECT_SOURCE_DIR}/api)
+gmx_register_gtest_test(${testname} ${exename} INTEGRATION_TEST)
+add_dependencies(check-nblib ${exename})
diff --git a/api/nblib/tests/box.cpp b/api/nblib/tests/box.cpp
new file mode 100644 (file)
index 0000000..4527033
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * This implements basic nblib box tests
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#include <cmath>
+
+#include "nblib/box.h"
+#include "nblib/exception.h"
+
+#include "testutils/refdata.h"
+#include "testutils/testasserts.h"
+
+using gmx::test::defaultRealTolerance;
+
+namespace nblib
+{
+
+TEST(NBlibTest, CubicBoxCannotHaveNaN)
+{
+    real number = NAN;
+    EXPECT_THROW(Box box(number), InputException);
+}
+
+TEST(NBlibTest, CubicBoxCannotHaveInf)
+{
+    real number = INFINITY;
+    EXPECT_THROW(Box box(number), InputException);
+}
+
+TEST(NBlibTest, RectangularBoxCannotHaveNaN)
+{
+    real number = NAN;
+    EXPECT_THROW(Box box(number, real(1.), real(1.)), InputException);
+}
+
+TEST(NBlibTest, RectangularBoxCannotHaveInf)
+{
+    real number = INFINITY;
+    EXPECT_THROW(Box box(number, real(1.), real(1.)), InputException);
+}
+
+TEST(NBlibTest, CubicBoxWorks)
+{
+    real              length = 3;
+    Box::LegacyMatrix ref    = { { length, 0, 0 }, { 0, length, 0 }, { 0, 0, length } };
+    Box               test   = Box(length);
+
+    for (int i = 0; i < dimSize; ++i)
+        for (int j = 0; j < dimSize; ++j)
+            EXPECT_REAL_EQ_TOL(ref[i][j], test.legacyMatrix()[i][j], defaultRealTolerance());
+}
+
+} // namespace nblib
diff --git a/api/nblib/tests/testhelpers.cpp b/api/nblib/tests/testhelpers.cpp
new file mode 100644 (file)
index 0000000..0884a06
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * This implements basic nblib test systems
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#include "nblib/tests/testhelpers.h"
+
+namespace nblib
+{
+namespace test
+{
+
+//! Compare between two instances of the Box object
+bool operator==(const Box& a, const Box& b)
+{
+    if (a.legacyMatrix()[XX][XX] != b.legacyMatrix()[XX][XX])
+    {
+        return false;
+    }
+    if (a.legacyMatrix()[YY][YY] != b.legacyMatrix()[YY][YY])
+    {
+        return false;
+    }
+    if (a.legacyMatrix()[ZZ][ZZ] != b.legacyMatrix()[ZZ][ZZ])
+    {
+        return false;
+    }
+    return true;
+}
+
+} // namespace test
+} // namespace nblib
diff --git a/api/nblib/tests/testhelpers.h b/api/nblib/tests/testhelpers.h
new file mode 100644 (file)
index 0000000..8f84602
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * This implements basic nblib test systems
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_TESTS_TESTHELPERS_H
+#define NBLIB_TESTS_TESTHELPERS_H
+
+#include "gromacs/math/vectypes.h"
+#include "gromacs/utility/arrayref.h"
+#include "nblib/box.h"
+#include "nblib/vector.h"
+
+#include "testutils/refdata.h"
+#include "testutils/testasserts.h"
+
+namespace nblib
+{
+
+namespace test
+{
+
+//! Compare between two instances of the Box object
+bool operator==(const Box& a, const Box& b);
+
+/*! \internal \brief
+ *  Simple test harness for checking 3D vectors like coordinates, velocities,
+ *  forces against reference data
+ *
+ */
+class Vector3DTest
+{
+public:
+    Vector3DTest() : checker_(refData_.rootChecker())
+    {
+        gmx::test::FloatingPointTolerance tolerance(
+                gmx::test::FloatingPointTolerance(1e-8, 1.0e-12, 1e-8, 1.0e-12, 200, 100, true));
+        checker_.setDefaultTolerance(tolerance);
+    }
+
+    //! Compare a given input vector of cartesians with the reference data
+    void testVectors(gmx::ArrayRef<Vec3> forces, const std::string& testString)
+    {
+        checker_.checkSequence(forces.begin(), forces.end(), testString.c_str());
+    }
+
+private:
+    gmx::test::TestReferenceData    refData_;
+    gmx::test::TestReferenceChecker checker_;
+};
+
+//! Macros to compare floats and doubles with a specified tolerance
+/// \cond DO_NOT_DOCUMENT
+#if GMX_DOUBLE
+#    define EXPECT_FLOAT_DOUBLE_EQ_TOL(value, refFloat, refDouble, tolerance) \
+        EXPECT_DOUBLE_EQ_TOL(value, refDouble, tolerance)
+#    define ASSERT_FLOAT_DOUBLE_EQ_TOL(value, refFloat, refDouble, tolerance) \
+        ASSERT_DOUBLE_EQ_TOL(value, refDouble, tolerance)
+#else
+#    define EXPECT_FLOAT_DOUBLE_EQ_TOL(value, refFloat, refDouble, tolerance) \
+        EXPECT_FLOAT_EQ_TOL(value, refFloat, tolerance)
+#    define ASSERT_FLOAT_DOUBLE_EQ_TOL(value, refFloat, refDouble, tolerance) \
+        ASSERT_FLOAT_EQ_TOL(value, refFloat, tolerance)
+#endif
+/// \endcond
+
+} // namespace test
+} // namespace nblib
+#endif // NBLIB_TESTS_TESTHELPERS_H
diff --git a/api/nblib/topology.h b/api/nblib/topology.h
new file mode 100644 (file)
index 0000000..17774c2
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib Topology and TopologyBuilder
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_TOPOLOGY_H
+#define NBLIB_TOPOLOGY_H
+
+#include <vector>
+
+#include "nblib/interactions.h"
+#include "nblib/molecules.h"
+#include "nblib/topologyhelpers.h"
+
+namespace gmx
+{
+template<typename>
+class ListOfLists;
+} // namespace gmx
+
+namespace nblib
+{
+
+/*! \inpublicapi
+ * \ingroup nblib
+ * \brief System Topology
+ *
+ * Contains all topology information meant to be used by the simulation
+ * engine internally. Private constructor ensures that a Topology object
+ * exists in a scope in a valid state after it has been built using a
+ * Topology Builder.
+ */
+class Topology final
+{
+
+public:
+    //! Returns the total number of particles in the system
+    int numParticles() const;
+
+    //! Returns a vector of particle types
+    std::vector<ParticleType> getParticleTypes() const;
+
+    //! Return the ParticleType ID of all particles
+    std::vector<int> getParticleTypeIdOfAllParticles() const;
+
+    //! Returns a vector of particles partial charges
+    std::vector<real> getCharges() const;
+
+    //! Returns exclusions in proper, performant, GROMACS layout
+    gmx::ListOfLists<int> getGmxExclusions() const;
+
+    //! Returns the unique ID of a specific particle belonging to a molecule in the global space
+    int sequenceID(MoleculeName moleculeName, int moleculeNr, ResidueName residueName, ParticleName particleName) const;
+
+    //! Returns a map of non-bonded force parameters indexed by ParticleType names
+    NonBondedInteractionMap getNonBondedInteractionMap() const;
+
+    //! Returns the combination rule used to generate the NonBondedInteractionMap
+    CombinationRule getCombinationRule() const;
+
+private:
+    Topology() = default;
+
+    friend class TopologyBuilder;
+
+    //! Total number of particles in the system
+    int numParticles_;
+    //! unique collection of ParticleTypes
+    std::vector<ParticleType> particleTypes_;
+    //! store an ID of each particles's type
+    std::vector<int> particleTypeIdOfAllParticles_;
+    //! Storage for particles partial charges
+    std::vector<real> charges_;
+    //! Information about exclusions.
+    gmx::ListOfLists<int> exclusions_;
+    //! Associate molecule, residue and particle names with sequence numbers
+    detail::ParticleSequencer particleSequencer_;
+    //! Map that should hold all nonbonded interactions for all particle types
+    NonBondedInteractionMap nonBondedInteractionMap_;
+    //! Combination Rule used to generate the nonbonded interactions
+    CombinationRule combinationRule_;
+};
+
+/*! \brief Topology Builder
+ *
+ * \libinternal
+ * \ingroup nblib
+ *
+ * A helper class to assist building of topologies. They also ensure that
+ * topologies only exist in a valid state within the scope of the
+ * simulation program.
+ *
+ */
+class TopologyBuilder final
+{
+public:
+    //! Constructor
+    TopologyBuilder();
+
+    /*! \brief
+     * Builds and Returns a valid Topology
+     *
+     * This function accounts for all the molecules added along with their
+     * exclusions and returns a topology with a valid state that is usable
+     * by the GROMACS back-end.
+     */
+    Topology buildTopology();
+
+    //! Adds a molecules of a certain type into the topology
+    TopologyBuilder& addMolecule(const Molecule& moleculeType, int nMolecules);
+
+    //! Add non-bonded interaction map to the topology
+    void addParticleTypesInteractions(const ParticleTypesInteractions& particleTypesInteractions);
+
+private:
+    //! Internally stored topology
+    Topology topology_;
+
+    //! Total number of particles in the system
+    int numParticles_;
+
+    //! List of molecule types and number of molecules
+    std::vector<std::tuple<Molecule, int>> molecules_;
+
+    //! Builds a GROMACS-compliant performant exclusions list aggregating exclusions from all molecules
+    gmx::ListOfLists<int> createExclusionsListOfLists() const;
+
+    //! Helper function to extract quantities like mass, charge, etc from the system
+    template<typename T, class Extractor>
+    std::vector<T> extractParticleTypeQuantity(Extractor&& extractor);
+
+    //! Distinct collection of ParticleTypes
+    std::unordered_map<std::string, ParticleType> particleTypes_;
+
+    //! ParticleType nonbonded parameters
+    ParticleTypesInteractions particleTypesInteractions_;
+};
+
+} // namespace nblib
+
+#endif // NBLIB_TOPOLOGY_H
diff --git a/api/nblib/topologyhelpers.h b/api/nblib/topologyhelpers.h
new file mode 100644 (file)
index 0000000..e67f646
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements helper functions needed for the nblib topology
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+#ifndef NBLIB_TOPOLOGY_HELPERS_H
+#define NBLIB_TOPOLOGY_HELPERS_H
+
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+#include "gromacs/utility/listoflists.h"
+#include "nblib/molecules.h"
+
+namespace gmx
+{
+struct ExclusionBlock;
+}
+
+namespace nblib
+{
+
+namespace detail
+{
+
+//! Converts tuples of particle indices to exclude to the gmx::ExclusionBlock format
+std::vector<gmx::ExclusionBlock> toGmxExclusionBlock(const std::vector<std::tuple<int, int>>& tupleList);
+
+//! Add offset to all indices in inBlock
+std::vector<gmx::ExclusionBlock> offsetGmxBlock(std::vector<gmx::ExclusionBlock> inBlock, int offset);
+
+//! Helper class for Topology to keep track of particle IDs
+class ParticleSequencer
+{
+    //! Alias for storing by (molecule name, molecule nr, residue name, particle name)
+    using DataType = std::unordered_map<
+            std::string,
+            std::unordered_map<int, std::unordered_map<std::string, std::unordered_map<std::string, int>>>>;
+
+public:
+    //! Build sequence from a list of molecules
+    void build(const std::vector<std::tuple<Molecule, int>>& moleculesList);
+
+    //! Access ID by (molecule name, molecule nr, residue name, particle name)
+    int operator()(const MoleculeName&, int, const ResidueName&, const ParticleName&) const;
+
+private:
+    DataType data_;
+};
+
+} // namespace detail
+
+} // namespace nblib
+
+#endif // NBLIB_TOPOLOGY_HELPERS_H
diff --git a/api/nblib/util/CMakeLists.txt b/api/nblib/util/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5bed936
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2020, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+#
+# \author Victor Holanda <victor.holanda@cscs.ch>
+# \author Joe Jordan <ejjordan@kth.se>
+# \author Prashanth Kanduri <kanduri@cscs.ch>
+# \author Sebastian Keller <keller@cscs.ch>
+#
+
+if(GMX_INSTALL_NBLIB_API)
+    install(FILES
+            user.h
+            DESTINATION include/nblib/util)
+endif()
diff --git a/api/nblib/util/user.h b/api/nblib/util/user.h
new file mode 100644 (file)
index 0000000..9d19189
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib utilities
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ */
+
+#ifndef NBLIB_UTIL_USER_H
+#define NBLIB_UTIL_USER_H
+
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <vector>
+
+#include "nblib/basicdefinitions.h"
+#include "nblib/vector.h"
+
+namespace nblib
+{
+
+//! Generate velocities from a Maxwell Boltzmann distribution, masses should be the
+//! same as the ones specified for the Topology object
+std::vector<Vec3> generateVelocity(real Temperature, unsigned int seed, std::vector<real> const& masses);
+
+//! Check within the container of gmx::RVecs for a NaN or inf
+bool checkNumericValues(const std::vector<Vec3>& values);
+
+//! Used to ignore unused arguments of a lambda functions
+inline void ignore_unused() {}
+
+//! Variadic argument version of the ignore_unused function
+template<class T, class... Ts>
+inline void ignore_unused(T& x, Ts&... xs)
+{
+    static_cast<void>(x);
+    ignore_unused(xs...);
+}
+
+/*! \brief A template to create structs as a type-safe alternative to using declarations
+ *
+ * \inpublicapi
+ * \ingroup nblib
+ *
+ * Used in public API functions where a distinction between different
+ * arguments of the same underlying type is desired. This provides a type-safe
+ * version to using declarations. Instead of naming a type alias, the name
+ * is used to define a struct that inherits from StrongType<T>, where T is
+ * the underlying type. For example:
+ *
+ * struct C6 : StrongType<real>
+ * {
+ *     using StrongType::StrongType;
+ *     using StrongType::operator=;
+ * };
+ *
+ * Due to the T() conversion and assignment from T,
+ * an instance of the resulting C6 struct behaves essentially like a real, while construction
+ * from real is disabled. This makes it impossible to pass a real as a function parameter
+ * of type C6.
+ */
+template<class T, class Phantom>
+struct StrongType
+{
+    //! default ctor
+    StrongType() : value_{} {}
+    //! construction from the underlying type T, implicit conversions disabled
+    explicit StrongType(T v) : value_(std::move(v)) {}
+
+    //! assignment from T
+    StrongType& operator=(T v)
+    {
+        value_ = std::move(v);
+        return *this;
+    }
+
+    //! conversion to T
+    operator T() const { return value_; }
+
+    //! access the underlying value
+    T value() const { return value_; }
+
+private:
+    T value_;
+};
+
+//! Equality comparison. For the case where a comparison between StrongTypes with matching T, but differing Phantom
+//! parameters is desired, the underlying value attribute should be compared instead
+template<class T, class Phantom>
+[[maybe_unused]] inline bool operator==(const StrongType<T, Phantom>& lhs, const StrongType<T, Phantom>& rhs)
+{
+    return lhs.value() == rhs.value();
+}
+
+//! comparison function <
+template<class T, class Phantom>
+inline bool operator<(const StrongType<T, Phantom>& lhs, const StrongType<T, Phantom>& rhs)
+{
+    return lhs.value() < rhs.value();
+}
+
+//! comparison function >
+template<class T, class Phantom>
+inline bool operator>(const StrongType<T, Phantom>& lhs, const StrongType<T, Phantom>& rhs)
+{
+    return lhs.value() > rhs.value();
+}
+
+
+//! Base template for a holder of entries of different data types
+template<class... Ts>
+struct TypeList
+{
+};
+
+//! Base template for mapping between a datatype P templated separately with instances of type list L
+template<template<class...> class P, class L>
+struct Map_
+{
+};
+
+//! this is a specialization of the Map_ base template
+//! for the case that the L template parameter itself has template parameters
+//! in this case, the template parameters of L are caught in Ts...
+template<template<class...> class P, template<class...> class L, class... Ts>
+struct Map_<P, L<Ts...>>
+{
+    //! resulting type is a TypeList of the P-template instantiated
+    //! with all template parameters of L
+    typedef TypeList<P<Ts>...> type;
+};
+
+//! Maps a datatype P to create instances where each is templated with entries of type list L
+template<template<class...> class P, class L>
+using Map = typename Map_<P, L>::type;
+
+//! Base template for expressing a datatype P templated with all the entries in type list L
+template<template<class...> class P, class L>
+struct Reduce_
+{
+};
+
+//! Specialization of the Reduce_ base template
+template<template<class...> class P, template<class...> class L, class... Ts>
+struct Reduce_<P, L<Ts...>>
+{
+    //! resulting type is P instantiated
+    //! with all template parameters of L
+    typedef P<Ts...> type;
+};
+
+//! Expresses a data type P instantiated with all the entries in list L as template arguments
+template<template<class...> class P, class L>
+using Reduce = typename Reduce_<P, L>::type;
+
+} // namespace nblib
+
+#endif // NBLIB_UTIL_USER_H
diff --git a/api/nblib/vector.h b/api/nblib/vector.h
new file mode 100644 (file)
index 0000000..4adec4c
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \inpublicapi \file
+ * \brief
+ * Implements nblib Cartesian coordinate vector
+ *
+ * \author Victor Holanda <victor.holanda@cscs.ch>
+ * \author Joe Jordan <ejjordan@kth.se>
+ * \author Prashanth Kanduri <kanduri@cscs.ch>
+ * \author Sebastian Keller <keller@cscs.ch>
+ */
+#ifndef NBLIB_BASICVECTOR_H
+#define NBLIB_BASICVECTOR_H
+
+#include "gromacs/math/vectypes.h"
+#include "nblib/basicdefinitions.h"
+
+namespace nblib
+{
+using Vec3 = gmx::BasicVector<real>;
+} // namespace nblib
+#endif // NBLIB_BASICVECTOR_H
index 24def5229319fd8867463b8be864e770b8cae065..2e985b5484811767b7582a38f54b5910589f0bd5 100644 (file)
@@ -551,6 +551,12 @@ if (SPHINX_FOUND)
             )
     endif ()
 
+    gmx_add_sphinx_source_files(
+            FILES
+            nblib/index.rst
+            nblib/guide-to-writing-MD-programs.rst
+    )
+
     gmx_add_sphinx_source_files(
         FILES
         ${REFERENCEMANUAL_SPHINX_FILES_GENERAL})
index 002cbe52cf9e560b8a7aadc3538ac6609ee13b11..354ef9e572e69ae1a1632d497a7fefa4955745e0 100644 (file)
@@ -25,6 +25,7 @@ Welcome to the |Gromacs| documentation!
            how-to/index
            reference-manual/index
            gmxapi/index
+          nblib/index
            dev-manual/index
         
         ==================
@@ -46,6 +47,7 @@ Welcome to the |Gromacs| documentation!
             how-to/index
             reference-manual/index
             gmxapi/index
+           nblib/index
             dev-manual/index
 
 
diff --git a/docs/nblib/guide-to-writing-MD-programs.rst b/docs/nblib/guide-to-writing-MD-programs.rst
new file mode 100644 (file)
index 0000000..2d6fd6a
--- /dev/null
@@ -0,0 +1,378 @@
+Guide to Writing MD Programs
+============================
+
+The goal of NB-LIB’s is to enable researchers to programmatically define molecular simulations.
+Traditionally these have been performed using a collection of executables and a manual workflow followed by a “black-box” simulation engine.
+NB-LIB allows users to script a variety of novel simulation and analysis workflows at a more granular level.
+
+Many possible use cases are facilitated by the flexibility that NB-LIB allows.
+These include customized update rules, defining custom forces, or orchestrating swarms of simulations.
+NB-LIB also allows for writing conventional MD simulations and analysis.
+
+This document goes over the steps to write MD programs using the API in NB-LIB that exposes features that are a part of the GROMACS package.
+
+Global Definitions
+------------------
+
+NB-LIB programs are written in C++ so its headers for I/O or advanced tasks must be included.
+In addition, one must include the headers for various capabilities and abstractions NB-LIB exposes as well.
+This can be directly copied from here.
+Finally, we use the namespace ``nblib`` for the data structures defined in the library.
+The last line in the block allows one to skip this specifier each time a function or a data structure is used.
+
+.. code:: cpp
+
+   #include <cstdio>
+
+   #include "nblib/box.h"
+   #include "nblib/forcecalculator.h"
+   #include "nblib/integrator.h"
+   #include "nblib/molecules.h"
+   #include "nblib/nbkerneloptions.h"
+   #include "nblib/particletype.h"
+   #include "nblib/simulationstate.h"
+   #include "nblib/topology.h"
+
+   using namespace nblib;
+
+Define Particle Data
+--------------------
+
+.. code:: cpp
+
+   // Parameters from a GROMOS compatible force-field 2016H66
+
+   struct OWaterAtom
+   {
+       ParticleName         name = "Ow";
+       Mass                 mass = 15.999;
+       C6                   c6   = 0.0026173456;
+       C12                  c12  = 2.634129e-06;
+   };
+
+   struct HwAtom
+   {
+       ParticleName         name = "Hw";
+       Mass                 mass = 1.00784;
+       C6                   c6   = 0.0;
+       C12                  c12  = 0.0;  
+   };
+
+   struct CMethAtom
+   {
+       ParticleName         name = "Cm";
+       Mass                 mass = 12.0107;
+       C6                   c6   = 0.01317904;
+       C12                  c12  = 34.363044e-06;
+   };
+
+   struct HcAtom
+   {
+       ParticleName         name = "Hc";
+       Mass                 mass = 1.00784;
+       C6                   c6   = 8.464e-05;
+       C12                  c12  = 15.129e-09;  
+   };
+
+There can be as many structs of this kind as there are particle types in the system.
+Organizing the data like this is not strictly necessary, but is shown for the purpose of clarity.
+As shown here, there can be multiple particles that correspond to a single element as atomic mass can vary by molecular context.
+For example, the carbon atom in a carboxyl group would have different parameters from one in the methyl group.
+We can obtain the parameter set from any standard force-field, or generate new parameters to study new compounds or force fields.
+This example comes from the `2016H66 Parameter Set <https://pubs.acs.org/doi/10.1021/acs.jctc.6b00187>`__.
+
+Defining Coordinates, Velocities and Force Buffers
+--------------------------------------------------
+
+.. code:: cpp
+
+   std::vector<gmx::RVec> coordinates = {
+       { 0.794, 1.439, 0.610 }, { 1.397, 0.673, 1.916 }, { 0.659, 1.080, 0.573 },
+       { 1.105, 0.090, 3.431 }, { 1.741, 1.291, 3.432 }, { 1.936, 1.441, 5.873 },
+       { 0.960, 2.246, 1.659 }, { 0.382, 3.023, 2.793 }, { 0.053, 4.857, 4.242 },
+       { 2.655, 5.057, 2.211 }, { 4.114, 0.737, 0.614 }, { 5.977, 5.104, 5.217 },
+   };
+
+   std::vector<gmx::RVec> velocities = {
+       { 0.0055, -0.1400, 0.2127 }, { 0.0930, -0.0160, -0.0086 }, { 0.1678, 0.2476, -0.0660 },
+       { 0.1591, -0.0934, -0.0835 }, { -0.0317, 0.0573, 0.1453 }, { 0.0597, 0.0013, -0.0462 },
+       { 0.0484, -0.0357, 0.0168 }, { 0.0530, 0.0295, -0.2694 }, { -0.0550, -0.0896, 0.0494 },
+       { -0.0799, -0.2534, -0.0079 }, { 0.0436, -0.1557, 0.1849 }, { -0.0214, 0.0446, 0.0758},
+   };
+
+   std::vector<gmx::RVec> forces = {
+       { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 },
+       { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 },
+       { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 },
+       { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 }, { 0.0000, 0.0000, 0.0000 },
+   };
+
+We can initialize coordinates for our particles using ``std::vector`` of ``gmx::RVec`` which is a specific data type for holding 3D vector quantities. `Doxygen page on RVec here`__.
+
+  __ doxygen-ref-rvec_
+
+Writing the MD Program
+----------------------
+
+As with as any basic C++ program, there needs to be a ``main()`` function.
+
+
+Define ParticleTypes
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: cpp
+
+   int main()
+   {
+       // Bring the parameter structs to scope
+       OwAtom      owAtom;
+       HwAtom      hwAtom;
+       CMethAtom   cmethAtom;
+       HcAtom      hcAtom;
+     
+       // Create the particles
+       ParticleType Ow(owAtom.name, owAtom.mass);
+       ParticleType Hw(hwAtom.name, hwAtom.mass);
+       ParticleType Cm(cmethAtom.name, cmethAtom.mass);
+       ParticleType Hc(hcAtom.name, hcAtom.mass);
+
+As before, the helper struct to define ``ParticleType`` data is not strictly needed, but is shown for clarity.
+The line ``ParticleType CMethAtom(ParticleName("Cm"), Mass(12.0107));`` would be sufficient.
+
+Define Non-Bonded Interactions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: cpp
+
+   ParticleTypeInteractions interactions(CombinationRule::Geometric);
+
+   // add non-bonded interactions for the particle types
+   interactions.add(owAtom.name, owAtom.c6, owAtom.c12);
+   interactions.add(hwAtom.name, hwAtom.c6, hwAtom.c12);
+   interactions.add(cmethAtom.name, cmethAtom.c6, cmethAtom.c12);
+   interactions.add(hcAtom.name, hcAtom.c6, hcAtom.c12);
+
+For the Lennard-Jones interactions, we define a ``ParticleTypeInteractions`` object.
+Each particle of the ``ParticleType`` interacts with each other based on the ``C6`` and ``C12`` parameters.
+These parameters of the two different particles are averaged using ``Geometric`` or ``LorentzBerthelot`` ``CombinationRule``.
+More details `here <http://manual.gromacs.org/documentation/2019/reference-manual/functions/nonbonded-interactions.html#the-lennard-jones-interaction>`__.
+By default ``CombinationRule::Geometric`` is selected.
+
+We add the interaction parameters of each of the particle types into the ``ParticleTypeInteractions`` object.
+The result is a table that has interactions specified for all ``ParticleType`` pairs.
+The following matrix describes the pair-wise C6 parameter created using ``CombinationRule::Geometric``.
+
+== ====== === ======= =======
+#  Ow     Hw  Cm      Hc
+== ====== === ======= =======
+Ow 0.0026 0.0 0.42    4.7e-4
+Hw 0.0    0.0 0.0     0.0
+Cm 0.42   0.0 0.013   1.05e-3
+Hc 4.7e-4 0.0 1.05e-3 8.5e-5
+== ====== === ======= =======
+
+For a particular interaction pair, the user can also override the specified ``CombinationRule`` with custom parameters.
+The following overload would replace the parameters computed from a ``CombinationRule``  between ``Ow`` and ``Cm`` particle types.
+
+.. code:: cpp
+
+   interactions.add("Ow", "Cm", 0.42, 42e-6);
+
+To facilitate modular, reusable code, it is possible to combine multiple ``ParticleTypeInteractions`` objects.
+Assuming ``otherInteractions`` is defined, this can be done with ``interactions.merge(otherInteractions)``
+
+Define Molecules
+~~~~~~~~~~~~~~~~
+
+.. code:: cpp
+
+   Molecule water("Water");
+   Molecule methane("Methane");
+
+   water.addParticle(ParticleName("O"), Ow);
+   water.addParticle(ParticleName("H1"), Hw);
+   water.addParticle(ParticleName("H2"), Hw);
+
+   water.addExclusion("H1", "O");
+   water.addExclusion("H2", "O");
+
+   methane.addParticle(ParticleName("C"), Cm);
+   methane.addParticle(ParticleName("H1"), Hc);
+   methane.addParticle(ParticleName("H2"), Hc);
+   methane.addParticle(ParticleName("H3"), Hc);
+   methane.addParticle(ParticleName("H4"), Hc);
+
+   methane.addExclusion("H1", "C");
+   methane.addExclusion("H2", "C");
+   methane.addExclusion("H3", "C");
+   methane.addExclusion("H4", "C");
+
+We begin declaring molecules with their constituent particles.
+A string identifier must uniquely identify a specific particle within the molecule.
+It is also possible to define partial charges on each particle for the computation of Coulomb interactions.
+``water.addParticle(ParticleName("O"), Charge(-0.04), Ow);``
+
+Adding exclusions ensures that non-bonded interactions are only computed when necessary.
+For example, if two  particles share a bond, the potential energy of the bond makes the non-bonded term negligible.
+Particle self-exclusions are enabled by default.
+We use the unique identifiers specified during ``addParticle()`` for this and the listed interactions later.
+
+Define Listed Interactions
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Within a molecule, one can define interactions such as bonds, angles and dihedrals between the constituent particles.
+NB-LIB provides concrete implementations of several commonly used 2, 3 and 4 center interactions.
+
+.. code:: cpp
+
+   HarmonicBondType ohHarmonicBond(1, 1);
+   HarmonicBondType hcHarmonicBond(2, 1);
+
+   DefaultAngle hohAngle(Degrees(120), 1);
+   DefaultAngle hchAngle(Degrees(109.5), 1);
+
+   //add harmonic bonds for water
+   water.addInteraction("O", "H1", ohHarmonicBond);
+   water.addInteraction("O", "H2", ohHarmonicBond);
+
+   // add the angle for water
+   water.addInteraction("H1", "O", "H2", hohAngle);
+
+   // add harmonic bonds for methane
+   methane.addInteraction("H1", "C", hcHarmonicBond);
+   methane.addInteraction("H2", "C", hcHarmonicBond);
+   methane.addInteraction("H3", "C", hcHarmonicBond);
+   methane.addInteraction("H4", "C", hhcHarmonicBondc);
+
+   // add the angles for methane
+   methane.addInteraction("H1", "C", "H2", hchAngle);
+   methane.addInteraction("H1", "C", "H3", hchAngle);
+   methane.addInteraction("H1", "C", "H4", hchAngle);
+   methane.addInteraction("H2", "C", "H3", hchAngle);
+   methane.addInteraction("H2", "C", "H4", hchAngle);
+   methane.addInteraction("H3", "C", "H4", hchAngle);
+
+Define Options for the Simulation and Non-Bonded Calculations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: cpp
+
+   // Define a box for the simulation
+   Box box(6.05449);
+
+   // Define options for the non-bonded kernels
+   NBKernelOptions options;
+
+One can define the bounding box either with a single argument for a cube and 3 arguments to specify length, breadth and height separately.
+
+``NBKernelOptions`` contains a set of flags and configuration options for both hardware context and the relevant calculations for the simulation.
+The following table describes the possible options that can be set.
+
++----------------------+------+---------------------------------------+
+| Flag or Config       | Type | Implications                          |
+| Option               |      |                                       |
++======================+======+=======================================+
+| ``useGpu``           | Bool | Use GPU for non-bonded computations   |
+|                      | ean  |                                       |
++----------------------+------+---------------------------------------+
+| ``numThreads``       | Inte | Number of CPU threads to use          |
+|                      | ger  |                                       |
++----------------------+------+---------------------------------------+
+| ``nbnxmSimd``        | Enum | Kernel SIMD type                      |
+|                      |      | (``SimdAuto``/``SimdNo``/``Simd4XM``/ |
+|                      |      | ``Simd2XMM``)                         |
++----------------------+------+---------------------------------------+
+| ``ljCombination      | Enum | Lennard-Jones combination rule        |
+| Rule``               |      | (``Geometric``/``LorentzBerthelot``)  |
++----------------------+------+---------------------------------------+
+| ``useHalfLJOptimizat | Bool | Enable i-cluster half-LJ optimization |
+| ion``                | ean  |                                       |
++----------------------+------+---------------------------------------+
+| ``pairlistCutoff``   | Real | Specify pairlist and interaction      |
+|                      |      | cut-off                               |
++----------------------+------+---------------------------------------+
+| ``computeVirialAndEn | Bool | Enable energy computations            |
+| ergy``               | ean  |                                       |
++----------------------+------+---------------------------------------+
+| ``coulombType``      | Enum | Coulomb interaction function          |
+|                      |      | (``Pme``/``Cutoff``/``ReactionField`` |
+|                      |      | )                                     |
++----------------------+------+---------------------------------------+
+| ``useTabulatedEwaldC | Bool | Use tabulated PME grid correction     |
+| orr``                | ean  | instead of analytical                 |
++----------------------+------+---------------------------------------+
+| ``numIterations``    | Inte | Specify number of iterations for each |
+|                      | ger  | kernel                                |
++----------------------+------+---------------------------------------+
+| ``cyclesPerPair``    | Bool | Enable printing cycles/pair instead   |
+|                      | ean  | of pairs/cycle                        |
++----------------------+------+---------------------------------------+
+| ``timestep``         | Real | Specify the time step                 |
++----------------------+------+---------------------------------------+
+
+Define Topology and Simulation State
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We build the system topology using the ``TopologyBuilder`` class.
+We add the ``Molecule`` objects that we defined previously along with the ``ParticleTypesInteractions`` using its public functions.
+We get the actual ``Topology`` object complete with all exclusions, interaction maps and listed interaction data constructed based on the defined entities using the ``buildTopology()``\ function.
+
+.. code:: cpp
+
+   TopologyBuilder topologyBuilder;
+
+   // add molecules
+   topologyBuilder.addMolecule(water, 10);
+   topologyBuilder.addMolecule(methane, 10);
+
+   // add non-bonded interaction map
+   topologyBuilder.addParticleTypesInteractions(interactions);
+
+   Topology topology = topologyBuilder.buildTopology();
+
+We now have all we need to fully describe our system using the ``SimulationState`` object.
+This is built using the topology, the box, and the particle coordinates and velocities.
+This object serves as a snapshot of the system that can be used for analysis or to start simulations from known states.
+
+.. code:: cpp
+
+   SimulationState simulationState(coordinates, velocities, forces, box, topology);
+
+
+
+Writing the MD Loop
+~~~~~~~~~~~~~~~~~~~
+
+Now that we have fully described our system and the problem, we need two entities to write an MD loop.
+The first is the ``ForceCalculator`` and the second is an Integrator.
+NB-LIB comes with a ``LeapFrog`` integrator but it is also possible for users to write custom integrators.
+
+.. code:: cpp
+
+   // The force calculator contains all the data needed to compute forces
+   ForceCalculator forceCalculator(simulationState, options);
+
+   // Integration requires masses, positions, and forces
+   LeapFrog integrator(simulationState);
+
+   // Allocate a force buffer
+   gmx::ArrayRef<gmx::RVec> userForces(topology.numParticles());
+
+   // MD Loop
+   int numSteps = 100;
+
+   for (i = 0; i < numSteps; i++)
+   {
+     userForces = forceCalculator.compute();
+
+     // The forces are not automatically updated in case the user wants to add their own
+     std::copy(userForces.begin(), userForces.end(), begin(simulationState.forces()));
+
+     // Integrate with a time step of 1 fs
+     integrator.integrate(1.0);
+   }
+
+   return 0;
+   } // main
+
+.. _doxygen-ref-rvec: ../doxygen/html-lib/namespacegmx.xhtml#a139c1919a9680de4ad1450f42e37d33b
\ No newline at end of file
diff --git a/docs/nblib/index.rst b/docs/nblib/index.rst
new file mode 100644 (file)
index 0000000..c90fe05
--- /dev/null
@@ -0,0 +1,15 @@
+.. _nblib:
+
+=========
+NBLIB API
+=========
+
+This documentation is part of the `GROMACS manual <http://manual.gromacs.org/current/>`_
+and describes the *nblib* API.
+
+
+..  toctree::
+    :maxdepth: 1
+    :caption: Documentation sections
+
+    guide-to-writing-MD-programs.rst