From: Joe Jordan Date: Mon, 28 Sep 2020 10:35:59 +0000 (+0000) Subject: Add initial nblib public API X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=d1db0d0fb0141abb024ecabaf27a6b8daf6ea790;p=alexxy%2Fgromacs.git Add initial nblib public API --- diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index b9e91082db..327282eea8 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -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 index 0000000000..d92950b4de --- /dev/null +++ b/api/nblib/CMakeLists.txt @@ -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 +# \author Joe Jordan +# \author Prashanth Kanduri +# \author Sebastian Keller +# + +# 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 index 0000000000..41dabd3270 --- /dev/null +++ b/api/nblib/basicdefinitions.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_BASICDEFINITIONS_H +#define NBLIB_BASICDEFINITIONS_H + +#include + +// 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 index 0000000000..8d3c3778f4 --- /dev/null +++ b/api/nblib/box.cpp @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#include + +#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 index 0000000000..c1aaead24b --- /dev/null +++ b/api/nblib/box.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#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 index 0000000000..c83a53b2c2 --- /dev/null +++ b/api/nblib/exception.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#ifndef NBLIB_EXCEPTION_H +#define NBLIB_EXCEPTION_H + +#include +#include + +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 index 0000000000..7083da5418 --- /dev/null +++ b/api/nblib/forcecalculator.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#ifndef NBLIB_FORCECALCULATOR_H +#define NBLIB_FORCECALCULATOR_H + +#include "nblib/interactions.h" +#include "nblib/kerneloptions.h" +#include "nblib/simulationstate.h" + +namespace gmx +{ +template +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 coordinates, gmx::ArrayRef 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 particleInfoAllVdW, + gmx::ArrayRef coordinates, + const Box& box); + +private: + //! GROMACS force calculator to compute forces + std::unique_ptr gmxForceCalculator_; +}; + +} // namespace nblib + +#endif // NBLIB_FORCECALCULATOR_H diff --git a/api/nblib/integrator.h b/api/nblib/integrator.h new file mode 100644 index 0000000000..f72d6b46d1 --- /dev/null +++ b/api/nblib/integrator.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_INTEGRATOR_H +#define NBLIB_INTEGRATOR_H + +#include + +#include "nblib/box.h" +#include "nblib/vector.h" + +namespace gmx +{ +template +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 coordinates, + gmx::ArrayRef velocities, + gmx::ArrayRef forces); + +private: + //! 1/mass for all atoms + std::vector 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 index 0000000000..7a3e24501d --- /dev/null +++ b/api/nblib/interactions.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_INTERACTIONS_H +#define NBLIB_INTERACTIONS_H + +#include +#include +#include + +#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; +//! Named type for the C12 parameter in the Lennard-Jones potential +using C12 = StrongType; + +using NonBondedInteractionMapImpl = + std::map, std::tuple>; + +//! Map used for looking up non-bonded parameters using particle types +class NonBondedInteractionMap final +{ +private: + using NamePairTuple = std::tuple; + using ComboParameters = std::tuple; + using InteractionMap = std::map; + 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> singleParticleInteractionsMap_; + std::map, std::tuple> twoParticlesInteractionsMap_; +}; + +} // namespace nblib +#endif // NBLIB_INTERACTIONS_H diff --git a/api/nblib/kerneloptions.h b/api/nblib/kerneloptions.h new file mode 100644 index 0000000000..dfd72e74ca --- /dev/null +++ b/api/nblib/kerneloptions.h @@ -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 + * \author Victor Holanda + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#ifndef NBLIB_KERNELOPTIONS_H +#define NBLIB_KERNELOPTIONS_H + +#include + +#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 index 0000000000..afcae8ccbd --- /dev/null +++ b/api/nblib/molecules.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + * + * \inpublicapi + * \ingroup nblib + */ +#ifndef NBLIB_MOLECULES_H +#define NBLIB_MOLECULES_H + +#include +#include +#include +#include + +#include "nblib/particletype.h" + +namespace nblib +{ +//! Named type for unique identifier for a particle in a molecule +using ParticleName = StrongType; + +//! Named type for charges on a particle within a molecule +using Charge = StrongType; + +//! Named type for residue name used to diffentiate between sections of a molecule +using ResidueName = StrongType; + +//! Named type for the name of a molecule +using MoleculeName = StrongType; + +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 particle, + std::tuple 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> 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() const; + + //! Return map of particle types and their names + std::unordered_map particleTypesMap() const; + + //! The molecule name + MoleculeName name() const; + +private: + //! Name of the molecule + MoleculeName name_; + + //! one entry per particle in molecule + std::vector particles_; + + //! collection of distinct particle types in molecule + std::unordered_map particleTypes_; + + //! Used for calculated exclusions based on particle indices in molecule + std::vector> exclusions_; + + //! we cannot efficiently compute indices during the build-phase + //! so we delay the conversion until TopologyBuilder requests it + std::vector> exclusionsByName_; +}; + +} // namespace nblib +#endif // NBLIB_MOLECULES_H diff --git a/api/nblib/nblib.h b/api/nblib/nblib.h new file mode 100644 index 0000000000..55c510a577 --- /dev/null +++ b/api/nblib/nblib.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#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 index 0000000000..432bdb4ee3 --- /dev/null +++ b/api/nblib/particletype.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + * + * \inpublicapi + * \ingroup nblib + */ +#ifndef NBLIB_PARTICLETYPE_H +#define NBLIB_PARTICLETYPE_H + +#include + +#include "nblib/util/user.h" + +namespace nblib +{ +class TopologyBuilder; + +//! Named type for particle type name +using ParticleTypeName = StrongType; +//! Named type for particle mass +using Mass = StrongType; + +/*! \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 index 0000000000..db93eb5b60 --- /dev/null +++ b/api/nblib/simulationstate.h @@ -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 + * \author Victor Holanda + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_SIMULATIONSTATE_H +#define NBLIB_SIMULATIONSTATE_H + +#include +#include + +#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& coordinates, + const std::vector& velocities, + const std::vector& 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& coordinates(); + + //! Returns a read-only vector of particle coordinates + const std::vector& coordinates() const; + + //! Returns a reference to a (modifiable) vector of particle velocities + std::vector& velocities(); + + //! Returns a reference to a (modifiable) vector of forces + std::vector& forces(); + +private: + class Impl; + std::shared_ptr 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 index 0000000000..7646a52da1 --- /dev/null +++ b/api/nblib/tests/CMakeLists.txt @@ -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 +# \author Joe Jordan +# \author Prashanth Kanduri +# \author Sebastian Keller +# + +# 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 index 0000000000..4527033c6f --- /dev/null +++ b/api/nblib/tests/box.cpp @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#include + +#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 index 0000000000..0884a06d26 --- /dev/null +++ b/api/nblib/tests/testhelpers.cpp @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#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 index 0000000000..8f84602627 --- /dev/null +++ b/api/nblib/tests/testhelpers.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#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 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 index 0000000000..17774c2f77 --- /dev/null +++ b/api/nblib/topology.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_TOPOLOGY_H +#define NBLIB_TOPOLOGY_H + +#include + +#include "nblib/interactions.h" +#include "nblib/molecules.h" +#include "nblib/topologyhelpers.h" + +namespace gmx +{ +template +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 getParticleTypes() const; + + //! Return the ParticleType ID of all particles + std::vector getParticleTypeIdOfAllParticles() const; + + //! Returns a vector of particles partial charges + std::vector getCharges() const; + + //! Returns exclusions in proper, performant, GROMACS layout + gmx::ListOfLists 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 particleTypes_; + //! store an ID of each particles's type + std::vector particleTypeIdOfAllParticles_; + //! Storage for particles partial charges + std::vector charges_; + //! Information about exclusions. + gmx::ListOfLists 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> molecules_; + + //! Builds a GROMACS-compliant performant exclusions list aggregating exclusions from all molecules + gmx::ListOfLists createExclusionsListOfLists() const; + + //! Helper function to extract quantities like mass, charge, etc from the system + template + std::vector extractParticleTypeQuantity(Extractor&& extractor); + + //! Distinct collection of ParticleTypes + std::unordered_map 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 index 0000000000..e67f64619a --- /dev/null +++ b/api/nblib/topologyhelpers.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ +#ifndef NBLIB_TOPOLOGY_HELPERS_H +#define NBLIB_TOPOLOGY_HELPERS_H + +#include +#include +#include + +#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 toGmxExclusionBlock(const std::vector>& tupleList); + +//! Add offset to all indices in inBlock +std::vector offsetGmxBlock(std::vector 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>>>; + +public: + //! Build sequence from a list of molecules + void build(const std::vector>& 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 index 0000000000..5bed93690d --- /dev/null +++ b/api/nblib/util/CMakeLists.txt @@ -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 +# \author Joe Jordan +# \author Prashanth Kanduri +# \author Sebastian Keller +# + +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 index 0000000000..9d19189c4e --- /dev/null +++ b/api/nblib/util/user.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + * \author Artem Zhmurov + */ + +#ifndef NBLIB_UTIL_USER_H +#define NBLIB_UTIL_USER_H + +#include +#include +#include +#include +#include +#include +#include + +#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 generateVelocity(real Temperature, unsigned int seed, std::vector const& masses); + +//! Check within the container of gmx::RVecs for a NaN or inf +bool checkNumericValues(const std::vector& values); + +//! Used to ignore unused arguments of a lambda functions +inline void ignore_unused() {} + +//! Variadic argument version of the ignore_unused function +template +inline void ignore_unused(T& x, Ts&... xs) +{ + static_cast(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, where T is + * the underlying type. For example: + * + * struct C6 : StrongType + * { + * 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 +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 +[[maybe_unused]] inline bool operator==(const StrongType& lhs, const StrongType& rhs) +{ + return lhs.value() == rhs.value(); +} + +//! comparison function < +template +inline bool operator<(const StrongType& lhs, const StrongType& rhs) +{ + return lhs.value() < rhs.value(); +} + +//! comparison function > +template +inline bool operator>(const StrongType& lhs, const StrongType& rhs) +{ + return lhs.value() > rhs.value(); +} + + +//! Base template for a holder of entries of different data types +template +struct TypeList +{ +}; + +//! Base template for mapping between a datatype P templated separately with instances of type list L +template 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 class P, template class L, class... Ts> +struct Map_> +{ + //! resulting type is a TypeList of the P-template instantiated + //! with all template parameters of L + typedef TypeList...> type; +}; + +//! Maps a datatype P to create instances where each is templated with entries of type list L +template class P, class L> +using Map = typename Map_::type; + +//! Base template for expressing a datatype P templated with all the entries in type list L +template class P, class L> +struct Reduce_ +{ +}; + +//! Specialization of the Reduce_ base template +template class P, template class L, class... Ts> +struct Reduce_> +{ + //! resulting type is P instantiated + //! with all template parameters of L + typedef P type; +}; + +//! Expresses a data type P instantiated with all the entries in list L as template arguments +template class P, class L> +using Reduce = typename Reduce_::type; + +} // namespace nblib + +#endif // NBLIB_UTIL_USER_H diff --git a/api/nblib/vector.h b/api/nblib/vector.h new file mode 100644 index 0000000000..4adec4c4a4 --- /dev/null +++ b/api/nblib/vector.h @@ -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 + * \author Joe Jordan + * \author Prashanth Kanduri + * \author Sebastian Keller + */ +#ifndef NBLIB_BASICVECTOR_H +#define NBLIB_BASICVECTOR_H + +#include "gromacs/math/vectypes.h" +#include "nblib/basicdefinitions.h" + +namespace nblib +{ +using Vec3 = gmx::BasicVector; +} // namespace nblib +#endif // NBLIB_BASICVECTOR_H diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 24def52293..2e985b5484 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -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}) diff --git a/docs/index.rst b/docs/index.rst index 002cbe52cf..354ef9e572 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 index 0000000000..2d6fd6ac83 --- /dev/null +++ b/docs/nblib/guide-to-writing-MD-programs.rst @@ -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 + + #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 `__. + +Defining Coordinates, Velocities and Force Buffers +-------------------------------------------------- + +.. code:: cpp + + std::vector 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 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 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 `__. +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 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 index 0000000000..c90fe058d5 --- /dev/null +++ b/docs/nblib/index.rst @@ -0,0 +1,15 @@ +.. _nblib: + +========= +NBLIB API +========= + +This documentation is part of the `GROMACS manual `_ +and describes the *nblib* API. + + +.. toctree:: + :maxdepth: 1 + :caption: Documentation sections + + guide-to-writing-MD-programs.rst