From 5b3d54a0b450aa98812bf45d7d73eb22ee798a04 Mon Sep 17 00:00:00 2001 From: yutaka Date: Tue, 12 Apr 2022 14:32:52 +0900 Subject: [PATCH 01/12] doc: fix link in GlobalForceField --- book/content.en/docs/reference/forcefields/global/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/content.en/docs/reference/forcefields/global/_index.md b/book/content.en/docs/reference/forcefields/global/_index.md index f777d9d42..6c5caf6aa 100644 --- a/book/content.en/docs/reference/forcefields/global/_index.md +++ b/book/content.en/docs/reference/forcefields/global/_index.md @@ -12,11 +12,11 @@ bookCollapseSection = true It depends on the distances between two particles. -## [3SPN2BaseBase](3SPN2BaseBaseInteraction.md) +## [3SPN2BaseBase]({{}}) It is specific to 3SPN2 Coarse-Grained DNA model. -## [ProteinDNANonSpecific](ProteinDNANonSpecificInteraction.md) +## [ProteinDNANonSpecific]({{}}) It is a Coarse-Grained hydrogen bond model. From e6b5af911b29d2d6a838c0bb1531a20756f13c1c Mon Sep 17 00:00:00 2001 From: yutaka Date: Thu, 14 Apr 2022 14:39:25 +0900 Subject: [PATCH 02/12] doc: fix typo in UniformLennardJonesPotential.md --- .../forcefields/global/pair/UniformLennardJonesPotential.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/content.en/docs/reference/forcefields/global/pair/UniformLennardJonesPotential.md b/book/content.en/docs/reference/forcefields/global/pair/UniformLennardJonesPotential.md index 8990234df..906e93441 100644 --- a/book/content.en/docs/reference/forcefields/global/pair/UniformLennardJonesPotential.md +++ b/book/content.en/docs/reference/forcefields/global/pair/UniformLennardJonesPotential.md @@ -38,7 +38,7 @@ parameters = [ - The cutoff distance relative to the maximum {{}}\sigma_{ij}{{}}. - `index`: Integer - The index of the particle. -- `offset`: Integer (ptional. By default, 0.) +- `offset`: Integer (optional. By default, 0.) - Offset of the index. - `sigma`: Floating - It determines the effective particle size. From f691d6988bb60ebe466e177436110894cda16d1e Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:01:34 +0900 Subject: [PATCH 03/12] feat: add harmonic potential for external distance interaction --- mjolnir/forcefield/external/CMakeLists.txt | 1 + .../external/HarmonicGroovePotential.cpp | 11 +++ .../external/HarmonicGroovePotential.hpp | 93 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 mjolnir/forcefield/external/HarmonicGroovePotential.cpp create mode 100644 mjolnir/forcefield/external/HarmonicGroovePotential.hpp diff --git a/mjolnir/forcefield/external/CMakeLists.txt b/mjolnir/forcefield/external/CMakeLists.txt index f38cd2e28..e34da6bfa 100644 --- a/mjolnir/forcefield/external/CMakeLists.txt +++ b/mjolnir/forcefield/external/CMakeLists.txt @@ -2,6 +2,7 @@ set(mjolnir_forcefield_external_cpp_files "${CMAKE_CURRENT_SOURCE_DIR}/ExcludedVolumeWallPotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ImplicitMembranePotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/LennardJonesWallPotential.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/HarmonicGroovePotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RectangularBoxInteraction.cpp" ) set(mjolnir_forcefield_cpp_files diff --git a/mjolnir/forcefield/external/HarmonicGroovePotential.cpp b/mjolnir/forcefield/external/HarmonicGroovePotential.cpp new file mode 100644 index 000000000..c44402d83 --- /dev/null +++ b/mjolnir/forcefield/external/HarmonicGroovePotential.cpp @@ -0,0 +1,11 @@ +#include + +#ifndef MJOLNIR_SEPARATE_BUILD +#error "MJOLNIR_SEPARATE_BUILD flag is required" +#endif + +namespace mjolnir +{ +template class HarmonicGroovePotential; +template class HarmonicGroovePotential; +} // mjolnir diff --git a/mjolnir/forcefield/external/HarmonicGroovePotential.hpp b/mjolnir/forcefield/external/HarmonicGroovePotential.hpp new file mode 100644 index 000000000..e472ac97e --- /dev/null +++ b/mjolnir/forcefield/external/HarmonicGroovePotential.hpp @@ -0,0 +1,93 @@ +#ifndef MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP +#define MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP +#include +#include + +namespace mjolnir +{ + +/*! @brief harmonic potential * + * designed for external force field. Force particle-particle Harmonic potential, * + * see mjolnir/forcefield/local/HarmonicPotential.hpp */ +template +class HarmonicGroovePotential +{ + public: + using real_type = realT; + using parameter_type = std::pair; + using container_type = std::vector; + + static constexpr real_type default_cutoff() noexcept + { + return std::numeric_limits::max(); + } + static constexpr parameter_type default_parameter() noexcept + { + return std::make_pair(real_type(0), real_type(0)); + } + + public: + + HarmonicGroovePotential( + const std::vector>& params) + { + this->parameters_.resize(params.size()); + this->participants_.reserve(params.size()); + for(const auto& idxp : params) + { + const auto idx = idxp.first; + this->participants_.push_back(idx); + if(idx >= this->parameters_.size()) + { + this->parameters_.resize(idx+1, default_parameter()); + } + this->parameters_.at(idx) = idxp.second; + } + } + ~HarmonicGroovePotential(){} + + real_type potential(const std::size_t i, const real_type v) const noexcept + { + const parameter_type k_v0 = this->parameters_[i]; + const real_type dv = v - k_v0.second; + return k_v0.first * dv * dv; + } + + real_type derivative(const std::size_t i, const real_type v) const noexcept + { + const parameter_type k_v0 = this->parameters_[i]; + return 2 * k_v0.first * (v - k_v0.second); + } + + real_type max_cutoff_length() const noexcept + { + return this->default_cutoff(); + } + + std::vector const& participants() const noexcept + { + return participants_; + } + + // nothing to do when system parameters change. + template + void update(const System&) const noexcept {return;} + + const char* name() const noexcept {return "HarmonicGroove";} + + container_type& parameters() noexcept {return parameters_;} + container_type const& parameters() const noexcept {return parameters_;} + + private: + + container_type parameters_; + std::vector participants_; +}; + +#ifndef MJOLNIR_SEPARATE_BUILD +extern template class HarmonicGroovePotential; +extern template class HarmonicGroovePotential; +#endif // MJOLNIR_SEPARATE_BUILD + +} // mjolnir +#endif // MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP From 8e2c8d4f2e198120a6eab006fcaa89e6c0855d94 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:04:07 +0900 Subject: [PATCH 04/12] feat: implement interface for external harmonic potential --- mjolnir/input/read_external_interaction.hpp | 10 +++++++ mjolnir/input/read_external_potential.hpp | 29 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/mjolnir/input/read_external_interaction.hpp b/mjolnir/input/read_external_interaction.hpp index fb399c109..790a7e8f8 100644 --- a/mjolnir/input/read_external_interaction.hpp +++ b/mjolnir/input/read_external_interaction.hpp @@ -59,12 +59,22 @@ read_external_distance_interaction(const toml::value& external, shapeT&& shape) return make_unique(std::move(shape), read_excluded_volume_wall_potential(external)); } + else if(potential == "HarmonicGroove") + { + MJOLNIR_LOG_NOTICE("-- potential function is Harmonic."); + using potential_t = HarmonicGroovePotential; + using interaction_t = ExternalDistanceInteraction< + traitsT, potential_t, shapeT>; + return make_unique(std::move(shape), + read_harmonic_groove_potential(external)); + } else { throw_exception(toml::format_error("[error] " "mjolnir::read_external_distance_interaction: invalid potential", toml::find(external, "potential"), "here", { "expected value is one of the following.", + "- \"HarmonicGroove\" : attractive r^2 potential", "- \"ExcludedVolumeWall\": repulsive r^12 potential", "- \"LennardJonesWall\" : famous r^12 - r^6 potential", "- \"ImplicitMembrane\" : single-well interaction that models a membrane" diff --git a/mjolnir/input/read_external_potential.hpp b/mjolnir/input/read_external_potential.hpp index 3f853ce70..8211e80f9 100644 --- a/mjolnir/input/read_external_potential.hpp +++ b/mjolnir/input/read_external_potential.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,34 @@ read_excluded_volume_wall_potential(const toml::value& external) return potential_type(eps, cutoff, params); } +template +HarmonicGroovePotential +read_harmonic_groove_potential(const toml::value& external) +{ + MJOLNIR_GET_DEFAULT_LOGGER(); + MJOLNIR_LOG_FUNCTION(); + using real_type = realT; + using potential_type = HarmonicGroovePotential; + + const auto& env = external.contains("env") ? external.at("env") : toml::value{}; + + const auto& ps = toml::find(external, "parameters"); + MJOLNIR_LOG_INFO(ps.size(), " parameters are found"); + + std::vector>> params; + params.reserve(ps.size()); + for(const auto& param : ps) + { + const auto idx = find_parameter(param, env, "index") + + find_parameter_or(param, env, "offset", 0); + const auto k = find_parameter(param, env, "k"); + const auto v0 = find_parameter(param, env, "v0"); + params.emplace_back(idx, std::make_pair(k, v0)); + MJOLNIR_LOG_INFO("idx = ", idx, ", sigma = ", k, ", epsilon = ", v0); + } + return potential_type(params); +} + template ImplicitMembranePotential read_implicit_membrane_potential(const toml::value& external) From 782e6da287e6c2158c676801deb1e18a143a6d44 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:05:36 +0900 Subject: [PATCH 05/12] test: add test for harmonic potential for external distance interaction --- test/core/CMakeLists.txt | 2 + test/core/test_harmonic_groove_potential.cpp | 48 +++++++++++ .../test_read_harmonic_groove_potential.cpp | 83 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 test/core/test_harmonic_groove_potential.cpp create mode 100644 test/core/test_read_harmonic_groove_potential.cpp diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index 7c5d90e9a..45e7a37d4 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -43,6 +43,7 @@ set(TEST_NAMES test_implicit_membrane_potential test_excluded_volume_wall_potential test_lennard_jones_wall_potential + test_harmonic_groove_potential test_axis_aligned_plane_shape test_bond_length_interaction @@ -105,6 +106,7 @@ set(TEST_NAMES test_read_isolf_potential test_read_excluded_volume_wall_potential test_read_lennard_jones_wall_potential + test_read_harmonic_groove_potential test_read_implicit_membrane_potential test_read_uniform_potential diff --git a/test/core/test_harmonic_groove_potential.cpp b/test/core/test_harmonic_groove_potential.cpp new file mode 100644 index 000000000..2b00c215a --- /dev/null +++ b/test/core/test_harmonic_groove_potential.cpp @@ -0,0 +1,48 @@ +#define BOOST_TEST_MODULE "test_harmonic_groove_potential" + +#ifdef BOOST_TEST_DYN_LINK +#include +#else +#include +#endif + +#include + +BOOST_AUTO_TEST_CASE(HarmonicGroovePotential_double) +{ + using real_type = double; + constexpr static std::size_t N = 10000; + constexpr static real_type h = 1e-6; + constexpr static real_type tol = 1e-5; + + const real_type k = 1.0; + const real_type v0 = 1.0; + const std::vector>> + k_v0{{0u, {k, v0}}}; + + mjolnir::HarmonicGroovePotential hg(k_v0); + + const real_type test_range = 10.0; + const real_type z_min = v0 - test_range * 0.5; + const real_type z_max = v0 + test_range * 0.5; + const real_type dz = (z_max - z_min) / N; + + real_type z = z_min; + for(std::size_t i = 0; i < N; ++i) + { + const real_type pot1 = hg.potential(0, z + h); + const real_type pot2 = hg.potential(0, z - h); + const real_type dpot = (pot1 - pot2) / (2 * h); + const real_type deri = hg.derivative(0, z); + + if(std::abs(deri) > tol) + { + BOOST_TEST(dpot == deri, boost::test_tools::tolerance(tol)); + } + else + { + BOOST_TEST(deri == 0.0, boost::test_tools::tolerance(tol)); + } + z += dz; + } +} diff --git a/test/core/test_read_harmonic_groove_potential.cpp b/test/core/test_read_harmonic_groove_potential.cpp new file mode 100644 index 000000000..eb9158759 --- /dev/null +++ b/test/core/test_read_harmonic_groove_potential.cpp @@ -0,0 +1,83 @@ +#define BOOST_TEST_MODULE "test_read_harmonic_groove_potential" + +#ifdef BOOST_TEST_DYN_LINK +#include +#else +#include +#endif + +#include +#include +#include + +using test_types = std::tuple; + +constexpr inline float tolerance_value(float) noexcept {return 1e-4;} +constexpr inline double tolerance_value(double) noexcept {return 1e08;} + +template +decltype(boost::test_tools::tolerance(std::declval())) +tolerance() {return boost::test_tools::tolerance(tolerance_value(Real()));} + +BOOST_AUTO_TEST_CASE_TEMPLATE(read_harmonic_groove_noenv, T, test_types) +{ + mjolnir::LoggerManager::set_default_logger("test_read_harmonic_groove.log"); + + using real_type = T; + { + using namespace toml::literals; + // TODO: enable to remove shape.margin line + const toml::value v = u8R"( + interaction = "Distance" + potential = "HarmonicGroove" + shape.name = "AxisAlignedPlane" + shape.axis = "+X" + shape.position = 1.0 + shape.margin = 1.0 + parameters = [ + {index = 0, k = 2.0, v0 = 1.5}, + {index = 9, k = 2.0, v0 = 1.5}, + ] + )"_toml; + + const auto g = mjolnir::read_harmonic_groove_potential(v); + + BOOST_TEST(g.participants().size() == 2u); + BOOST_TEST(g.participants().at(0) == 0u); + BOOST_TEST(g.participants().at(1) == 9u); + + BOOST_TEST(g.parameters().at( 0).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 9).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 0).second == real_type(1.5), tolerance()); + BOOST_TEST(g.parameters().at( 9).second == real_type(1.5), tolerance()); + } + + { + using namespace toml::literals; + // TODO: enable to remove shape.margin line + const toml::value v = u8R"( + interaction = "Distance" + potential = "HarmonicGroove" + shape.name = "AxisAlignedPlane" + shape.axis = "+X" + shape.position = 1.0 + shape.margin = 1.0 + parameters = [ + {index = 0, k = 2.0, v0 = 1.5}, + {index = 9, k = 2.0, v0 = 1.5}, + ] + )"_toml; + + const auto g = mjolnir::read_harmonic_groove_potential(v); + + BOOST_TEST(g.participants().size() == 2u); + BOOST_TEST(g.participants().at(0) == 0u); + BOOST_TEST(g.participants().at(1) == 9u); + + BOOST_TEST(g.parameters().at( 0).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 9).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 0).second == real_type(1.5), tolerance()); + BOOST_TEST(g.parameters().at( 9).second == real_type(1.5), tolerance()); + } + +} From f274a4767f37d6ca73402a119dc5012f322259b0 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:08:22 +0900 Subject: [PATCH 06/12] doc: add reference for the harmonic potential for external interaction --- .../distance/HarmonicGroovePotential.md | 36 +++++++++++++++++++ .../forcefields/external/distance/_index.md | 1 + .../distance/HarmonicGroovePotential.md | 36 +++++++++++++++++++ .../forcefields/external/distance/_index.md | 1 + 4 files changed, 74 insertions(+) create mode 100644 book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md create mode 100644 book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md diff --git a/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md b/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md new file mode 100644 index 000000000..276dc21e3 --- /dev/null +++ b/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md @@ -0,0 +1,36 @@ ++++ +title = "HarmonicGroove" +weight = 100000 ++++ + +# HarmonicGroovePotential + +It is a Harmonic potential between particle and a spatial structure. + +{{<>}} +U(r) = k(v - v_0)^2 +{{}} + +## Example + +```toml +[[forcefields.external]] +interaction = "Distance" +potential = "HarmonicGroove" +shape.name = "AxisAlignedPlane" +shape.axis = "X" +shape.position = 0.0 +shape.margin = 1.0 + +parameters = [ + {index = 0, k = 1.0, v0 = 1.0}, + # ... +] +``` + +## Input Reference + +- `k`: Floating + - It determines the strength of the potential. +- `v0`: Floating + - It determines the native length. diff --git a/book/content.en/docs/reference/forcefields/external/distance/_index.md b/book/content.en/docs/reference/forcefields/external/distance/_index.md index 77fddf9b1..73224af0a 100644 --- a/book/content.en/docs/reference/forcefields/external/distance/_index.md +++ b/book/content.en/docs/reference/forcefields/external/distance/_index.md @@ -31,6 +31,7 @@ parameters = [ - The following potentials are available. - [`"LennardJonesWall"`]({{}}) - [`"ExcludedVolumeWall"`]({{}}) + - [`"HarmonicGroove"`]({{}}) - [`"ImplicitMembrane"`]({{}}) - `shape`: Table - The shape and the position of a structure that interacts with particles. diff --git a/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md b/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md new file mode 100644 index 000000000..482b91b2c --- /dev/null +++ b/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md @@ -0,0 +1,36 @@ ++++ +title = "HarmonicGroove" +weight = 200000 ++++ + +# HarmonicGroovePotential + +シンプルな調和振動子ポテンシャルです。 + +{{}} +U(r) = k (v - v_0)^2 +{{}} + +## Example + +```toml +[[forcefields.external]] +interaction = "Distance" +potential = "HarmonicGroove" +shape.name = "AxisAlignedPlane" +shape.axis = "X" +shape.position = 0.0 +shape.margin = 1.0 + +parameters = [ + {index = 0, k = 1.0, v0 = 1.0}, + # ... +] +``` + +## Input Reference + +- `k`: 浮動小数点数型 + - ポテンシャルの強さを指定します。 +- `v0`: 浮動小数点数型 + - 最安定点を指定します。 diff --git a/book/content.ja/docs/reference/forcefields/external/distance/_index.md b/book/content.ja/docs/reference/forcefields/external/distance/_index.md index 77fddf9b1..73224af0a 100644 --- a/book/content.ja/docs/reference/forcefields/external/distance/_index.md +++ b/book/content.ja/docs/reference/forcefields/external/distance/_index.md @@ -31,6 +31,7 @@ parameters = [ - The following potentials are available. - [`"LennardJonesWall"`]({{}}) - [`"ExcludedVolumeWall"`]({{}}) + - [`"HarmonicGroove"`]({{}}) - [`"ImplicitMembrane"`]({{}}) - `shape`: Table - The shape and the position of a structure that interacts with particles. From d9fd5374e9ecd949d1f98a1e43b03d71a97ea670 Mon Sep 17 00:00:00 2001 From: yutaka Date: Tue, 12 Apr 2022 14:32:52 +0900 Subject: [PATCH 07/12] doc: fix link in GlobalForceField --- book/content.en/docs/reference/forcefields/global/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/content.en/docs/reference/forcefields/global/_index.md b/book/content.en/docs/reference/forcefields/global/_index.md index f777d9d42..6c5caf6aa 100644 --- a/book/content.en/docs/reference/forcefields/global/_index.md +++ b/book/content.en/docs/reference/forcefields/global/_index.md @@ -12,11 +12,11 @@ bookCollapseSection = true It depends on the distances between two particles. -## [3SPN2BaseBase](3SPN2BaseBaseInteraction.md) +## [3SPN2BaseBase]({{}}) It is specific to 3SPN2 Coarse-Grained DNA model. -## [ProteinDNANonSpecific](ProteinDNANonSpecificInteraction.md) +## [ProteinDNANonSpecific]({{}}) It is a Coarse-Grained hydrogen bond model. From 6918e6f010d7741c1bd908262dc488fda8e1722d Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:01:34 +0900 Subject: [PATCH 08/12] feat: add harmonic potential for external distance interaction --- mjolnir/forcefield/external/CMakeLists.txt | 1 + .../external/HarmonicGroovePotential.cpp | 11 +++ .../external/HarmonicGroovePotential.hpp | 93 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 mjolnir/forcefield/external/HarmonicGroovePotential.cpp create mode 100644 mjolnir/forcefield/external/HarmonicGroovePotential.hpp diff --git a/mjolnir/forcefield/external/CMakeLists.txt b/mjolnir/forcefield/external/CMakeLists.txt index f38cd2e28..e34da6bfa 100644 --- a/mjolnir/forcefield/external/CMakeLists.txt +++ b/mjolnir/forcefield/external/CMakeLists.txt @@ -2,6 +2,7 @@ set(mjolnir_forcefield_external_cpp_files "${CMAKE_CURRENT_SOURCE_DIR}/ExcludedVolumeWallPotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ImplicitMembranePotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/LennardJonesWallPotential.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/HarmonicGroovePotential.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/RectangularBoxInteraction.cpp" ) set(mjolnir_forcefield_cpp_files diff --git a/mjolnir/forcefield/external/HarmonicGroovePotential.cpp b/mjolnir/forcefield/external/HarmonicGroovePotential.cpp new file mode 100644 index 000000000..c44402d83 --- /dev/null +++ b/mjolnir/forcefield/external/HarmonicGroovePotential.cpp @@ -0,0 +1,11 @@ +#include + +#ifndef MJOLNIR_SEPARATE_BUILD +#error "MJOLNIR_SEPARATE_BUILD flag is required" +#endif + +namespace mjolnir +{ +template class HarmonicGroovePotential; +template class HarmonicGroovePotential; +} // mjolnir diff --git a/mjolnir/forcefield/external/HarmonicGroovePotential.hpp b/mjolnir/forcefield/external/HarmonicGroovePotential.hpp new file mode 100644 index 000000000..e472ac97e --- /dev/null +++ b/mjolnir/forcefield/external/HarmonicGroovePotential.hpp @@ -0,0 +1,93 @@ +#ifndef MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP +#define MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP +#include +#include + +namespace mjolnir +{ + +/*! @brief harmonic potential * + * designed for external force field. Force particle-particle Harmonic potential, * + * see mjolnir/forcefield/local/HarmonicPotential.hpp */ +template +class HarmonicGroovePotential +{ + public: + using real_type = realT; + using parameter_type = std::pair; + using container_type = std::vector; + + static constexpr real_type default_cutoff() noexcept + { + return std::numeric_limits::max(); + } + static constexpr parameter_type default_parameter() noexcept + { + return std::make_pair(real_type(0), real_type(0)); + } + + public: + + HarmonicGroovePotential( + const std::vector>& params) + { + this->parameters_.resize(params.size()); + this->participants_.reserve(params.size()); + for(const auto& idxp : params) + { + const auto idx = idxp.first; + this->participants_.push_back(idx); + if(idx >= this->parameters_.size()) + { + this->parameters_.resize(idx+1, default_parameter()); + } + this->parameters_.at(idx) = idxp.second; + } + } + ~HarmonicGroovePotential(){} + + real_type potential(const std::size_t i, const real_type v) const noexcept + { + const parameter_type k_v0 = this->parameters_[i]; + const real_type dv = v - k_v0.second; + return k_v0.first * dv * dv; + } + + real_type derivative(const std::size_t i, const real_type v) const noexcept + { + const parameter_type k_v0 = this->parameters_[i]; + return 2 * k_v0.first * (v - k_v0.second); + } + + real_type max_cutoff_length() const noexcept + { + return this->default_cutoff(); + } + + std::vector const& participants() const noexcept + { + return participants_; + } + + // nothing to do when system parameters change. + template + void update(const System&) const noexcept {return;} + + const char* name() const noexcept {return "HarmonicGroove";} + + container_type& parameters() noexcept {return parameters_;} + container_type const& parameters() const noexcept {return parameters_;} + + private: + + container_type parameters_; + std::vector participants_; +}; + +#ifndef MJOLNIR_SEPARATE_BUILD +extern template class HarmonicGroovePotential; +extern template class HarmonicGroovePotential; +#endif // MJOLNIR_SEPARATE_BUILD + +} // mjolnir +#endif // MJOLNIR_POTENTIAL_EXTERNAL_HARMONIC_GROOVE_POTENTIAL_HPP From 36207c491e57dcdf6e0a10f882fc4b1692b30a19 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:04:07 +0900 Subject: [PATCH 09/12] feat: implement interface for external harmonic potential --- mjolnir/input/read_external_interaction.hpp | 10 +++++++ mjolnir/input/read_external_potential.hpp | 29 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/mjolnir/input/read_external_interaction.hpp b/mjolnir/input/read_external_interaction.hpp index fb399c109..790a7e8f8 100644 --- a/mjolnir/input/read_external_interaction.hpp +++ b/mjolnir/input/read_external_interaction.hpp @@ -59,12 +59,22 @@ read_external_distance_interaction(const toml::value& external, shapeT&& shape) return make_unique(std::move(shape), read_excluded_volume_wall_potential(external)); } + else if(potential == "HarmonicGroove") + { + MJOLNIR_LOG_NOTICE("-- potential function is Harmonic."); + using potential_t = HarmonicGroovePotential; + using interaction_t = ExternalDistanceInteraction< + traitsT, potential_t, shapeT>; + return make_unique(std::move(shape), + read_harmonic_groove_potential(external)); + } else { throw_exception(toml::format_error("[error] " "mjolnir::read_external_distance_interaction: invalid potential", toml::find(external, "potential"), "here", { "expected value is one of the following.", + "- \"HarmonicGroove\" : attractive r^2 potential", "- \"ExcludedVolumeWall\": repulsive r^12 potential", "- \"LennardJonesWall\" : famous r^12 - r^6 potential", "- \"ImplicitMembrane\" : single-well interaction that models a membrane" diff --git a/mjolnir/input/read_external_potential.hpp b/mjolnir/input/read_external_potential.hpp index 3f853ce70..8211e80f9 100644 --- a/mjolnir/input/read_external_potential.hpp +++ b/mjolnir/input/read_external_potential.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,34 @@ read_excluded_volume_wall_potential(const toml::value& external) return potential_type(eps, cutoff, params); } +template +HarmonicGroovePotential +read_harmonic_groove_potential(const toml::value& external) +{ + MJOLNIR_GET_DEFAULT_LOGGER(); + MJOLNIR_LOG_FUNCTION(); + using real_type = realT; + using potential_type = HarmonicGroovePotential; + + const auto& env = external.contains("env") ? external.at("env") : toml::value{}; + + const auto& ps = toml::find(external, "parameters"); + MJOLNIR_LOG_INFO(ps.size(), " parameters are found"); + + std::vector>> params; + params.reserve(ps.size()); + for(const auto& param : ps) + { + const auto idx = find_parameter(param, env, "index") + + find_parameter_or(param, env, "offset", 0); + const auto k = find_parameter(param, env, "k"); + const auto v0 = find_parameter(param, env, "v0"); + params.emplace_back(idx, std::make_pair(k, v0)); + MJOLNIR_LOG_INFO("idx = ", idx, ", sigma = ", k, ", epsilon = ", v0); + } + return potential_type(params); +} + template ImplicitMembranePotential read_implicit_membrane_potential(const toml::value& external) From 8e314ba18b926384b3289309cc17908249b08b19 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:05:36 +0900 Subject: [PATCH 10/12] test: add test for harmonic potential for external distance interaction --- test/core/CMakeLists.txt | 2 + test/core/test_harmonic_groove_potential.cpp | 48 +++++++++++ .../test_read_harmonic_groove_potential.cpp | 83 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 test/core/test_harmonic_groove_potential.cpp create mode 100644 test/core/test_read_harmonic_groove_potential.cpp diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index a411392bb..3a8dd3b97 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -44,6 +44,7 @@ set(TEST_NAMES test_implicit_membrane_potential test_excluded_volume_wall_potential test_lennard_jones_wall_potential + test_harmonic_groove_potential test_axis_aligned_plane_shape test_bond_length_interaction @@ -107,6 +108,7 @@ set(TEST_NAMES test_read_isolf_potential test_read_excluded_volume_wall_potential test_read_lennard_jones_wall_potential + test_read_harmonic_groove_potential test_read_implicit_membrane_potential test_read_uniform_potential diff --git a/test/core/test_harmonic_groove_potential.cpp b/test/core/test_harmonic_groove_potential.cpp new file mode 100644 index 000000000..2b00c215a --- /dev/null +++ b/test/core/test_harmonic_groove_potential.cpp @@ -0,0 +1,48 @@ +#define BOOST_TEST_MODULE "test_harmonic_groove_potential" + +#ifdef BOOST_TEST_DYN_LINK +#include +#else +#include +#endif + +#include + +BOOST_AUTO_TEST_CASE(HarmonicGroovePotential_double) +{ + using real_type = double; + constexpr static std::size_t N = 10000; + constexpr static real_type h = 1e-6; + constexpr static real_type tol = 1e-5; + + const real_type k = 1.0; + const real_type v0 = 1.0; + const std::vector>> + k_v0{{0u, {k, v0}}}; + + mjolnir::HarmonicGroovePotential hg(k_v0); + + const real_type test_range = 10.0; + const real_type z_min = v0 - test_range * 0.5; + const real_type z_max = v0 + test_range * 0.5; + const real_type dz = (z_max - z_min) / N; + + real_type z = z_min; + for(std::size_t i = 0; i < N; ++i) + { + const real_type pot1 = hg.potential(0, z + h); + const real_type pot2 = hg.potential(0, z - h); + const real_type dpot = (pot1 - pot2) / (2 * h); + const real_type deri = hg.derivative(0, z); + + if(std::abs(deri) > tol) + { + BOOST_TEST(dpot == deri, boost::test_tools::tolerance(tol)); + } + else + { + BOOST_TEST(deri == 0.0, boost::test_tools::tolerance(tol)); + } + z += dz; + } +} diff --git a/test/core/test_read_harmonic_groove_potential.cpp b/test/core/test_read_harmonic_groove_potential.cpp new file mode 100644 index 000000000..eb9158759 --- /dev/null +++ b/test/core/test_read_harmonic_groove_potential.cpp @@ -0,0 +1,83 @@ +#define BOOST_TEST_MODULE "test_read_harmonic_groove_potential" + +#ifdef BOOST_TEST_DYN_LINK +#include +#else +#include +#endif + +#include +#include +#include + +using test_types = std::tuple; + +constexpr inline float tolerance_value(float) noexcept {return 1e-4;} +constexpr inline double tolerance_value(double) noexcept {return 1e08;} + +template +decltype(boost::test_tools::tolerance(std::declval())) +tolerance() {return boost::test_tools::tolerance(tolerance_value(Real()));} + +BOOST_AUTO_TEST_CASE_TEMPLATE(read_harmonic_groove_noenv, T, test_types) +{ + mjolnir::LoggerManager::set_default_logger("test_read_harmonic_groove.log"); + + using real_type = T; + { + using namespace toml::literals; + // TODO: enable to remove shape.margin line + const toml::value v = u8R"( + interaction = "Distance" + potential = "HarmonicGroove" + shape.name = "AxisAlignedPlane" + shape.axis = "+X" + shape.position = 1.0 + shape.margin = 1.0 + parameters = [ + {index = 0, k = 2.0, v0 = 1.5}, + {index = 9, k = 2.0, v0 = 1.5}, + ] + )"_toml; + + const auto g = mjolnir::read_harmonic_groove_potential(v); + + BOOST_TEST(g.participants().size() == 2u); + BOOST_TEST(g.participants().at(0) == 0u); + BOOST_TEST(g.participants().at(1) == 9u); + + BOOST_TEST(g.parameters().at( 0).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 9).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 0).second == real_type(1.5), tolerance()); + BOOST_TEST(g.parameters().at( 9).second == real_type(1.5), tolerance()); + } + + { + using namespace toml::literals; + // TODO: enable to remove shape.margin line + const toml::value v = u8R"( + interaction = "Distance" + potential = "HarmonicGroove" + shape.name = "AxisAlignedPlane" + shape.axis = "+X" + shape.position = 1.0 + shape.margin = 1.0 + parameters = [ + {index = 0, k = 2.0, v0 = 1.5}, + {index = 9, k = 2.0, v0 = 1.5}, + ] + )"_toml; + + const auto g = mjolnir::read_harmonic_groove_potential(v); + + BOOST_TEST(g.participants().size() == 2u); + BOOST_TEST(g.participants().at(0) == 0u); + BOOST_TEST(g.participants().at(1) == 9u); + + BOOST_TEST(g.parameters().at( 0).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 9).first == real_type(2.0), tolerance()); + BOOST_TEST(g.parameters().at( 0).second == real_type(1.5), tolerance()); + BOOST_TEST(g.parameters().at( 9).second == real_type(1.5), tolerance()); + } + +} From 3e05a8d464fe762a30fb6d3dbda4d92dcd562bb1 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Wed, 12 Oct 2022 20:08:22 +0900 Subject: [PATCH 11/12] doc: add reference for the harmonic potential for external interaction --- .../distance/HarmonicGroovePotential.md | 36 +++++++++++++++++++ .../forcefields/external/distance/_index.md | 1 + .../distance/HarmonicGroovePotential.md | 36 +++++++++++++++++++ .../forcefields/external/distance/_index.md | 1 + 4 files changed, 74 insertions(+) create mode 100644 book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md create mode 100644 book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md diff --git a/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md b/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md new file mode 100644 index 000000000..276dc21e3 --- /dev/null +++ b/book/content.en/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md @@ -0,0 +1,36 @@ ++++ +title = "HarmonicGroove" +weight = 100000 ++++ + +# HarmonicGroovePotential + +It is a Harmonic potential between particle and a spatial structure. + +{{<>}} +U(r) = k(v - v_0)^2 +{{}} + +## Example + +```toml +[[forcefields.external]] +interaction = "Distance" +potential = "HarmonicGroove" +shape.name = "AxisAlignedPlane" +shape.axis = "X" +shape.position = 0.0 +shape.margin = 1.0 + +parameters = [ + {index = 0, k = 1.0, v0 = 1.0}, + # ... +] +``` + +## Input Reference + +- `k`: Floating + - It determines the strength of the potential. +- `v0`: Floating + - It determines the native length. diff --git a/book/content.en/docs/reference/forcefields/external/distance/_index.md b/book/content.en/docs/reference/forcefields/external/distance/_index.md index 77fddf9b1..73224af0a 100644 --- a/book/content.en/docs/reference/forcefields/external/distance/_index.md +++ b/book/content.en/docs/reference/forcefields/external/distance/_index.md @@ -31,6 +31,7 @@ parameters = [ - The following potentials are available. - [`"LennardJonesWall"`]({{}}) - [`"ExcludedVolumeWall"`]({{}}) + - [`"HarmonicGroove"`]({{}}) - [`"ImplicitMembrane"`]({{}}) - `shape`: Table - The shape and the position of a structure that interacts with particles. diff --git a/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md b/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md new file mode 100644 index 000000000..482b91b2c --- /dev/null +++ b/book/content.ja/docs/reference/forcefields/external/distance/HarmonicGroovePotential.md @@ -0,0 +1,36 @@ ++++ +title = "HarmonicGroove" +weight = 200000 ++++ + +# HarmonicGroovePotential + +シンプルな調和振動子ポテンシャルです。 + +{{}} +U(r) = k (v - v_0)^2 +{{}} + +## Example + +```toml +[[forcefields.external]] +interaction = "Distance" +potential = "HarmonicGroove" +shape.name = "AxisAlignedPlane" +shape.axis = "X" +shape.position = 0.0 +shape.margin = 1.0 + +parameters = [ + {index = 0, k = 1.0, v0 = 1.0}, + # ... +] +``` + +## Input Reference + +- `k`: 浮動小数点数型 + - ポテンシャルの強さを指定します。 +- `v0`: 浮動小数点数型 + - 最安定点を指定します。 diff --git a/book/content.ja/docs/reference/forcefields/external/distance/_index.md b/book/content.ja/docs/reference/forcefields/external/distance/_index.md index 77fddf9b1..73224af0a 100644 --- a/book/content.ja/docs/reference/forcefields/external/distance/_index.md +++ b/book/content.ja/docs/reference/forcefields/external/distance/_index.md @@ -31,6 +31,7 @@ parameters = [ - The following potentials are available. - [`"LennardJonesWall"`]({{}}) - [`"ExcludedVolumeWall"`]({{}}) + - [`"HarmonicGroove"`]({{}}) - [`"ImplicitMembrane"`]({{}}) - `shape`: Table - The shape and the position of a structure that interacts with particles. From c0f4b248533fa289c0e34fdf9f7a7aae7e7b5ae5 Mon Sep 17 00:00:00 2001 From: yutakasi634 Date: Mon, 24 Oct 2022 17:20:05 +0900 Subject: [PATCH 12/12] feat: exchange reading order of external interaction --- mjolnir/input/read_external_interaction.cpp | 8 +- mjolnir/input/read_external_interaction.hpp | 169 ++++++++++---------- 2 files changed, 91 insertions(+), 86 deletions(-) diff --git a/mjolnir/input/read_external_interaction.cpp b/mjolnir/input/read_external_interaction.cpp index b6975bc91..b049f4e68 100644 --- a/mjolnir/input/read_external_interaction.cpp +++ b/mjolnir/input/read_external_interaction.cpp @@ -26,10 +26,10 @@ template std::unique_ptr>> read_afm_flexible_fitting_interaction(const toml::value&); template std::unique_ptr>> read_afm_flexible_fitting_interaction(const toml::value&); -template std::unique_ptr >> read_external_distance_interaction_shape(const toml::value& external); -template std::unique_ptr >> read_external_distance_interaction_shape(const toml::value& external); -template std::unique_ptr>> read_external_distance_interaction_shape(const toml::value& external); -template std::unique_ptr>> read_external_distance_interaction_shape(const toml::value& external); +template std::unique_ptr >> read_external_distance_interaction(const toml::value& external); +template std::unique_ptr >> read_external_distance_interaction(const toml::value& external); +template std::unique_ptr>> read_external_distance_interaction(const toml::value& external); +template std::unique_ptr>> read_external_distance_interaction(const toml::value& external); template std::unique_ptr >> read_pulling_force_interaction(const toml::value& external); template std::unique_ptr >> read_pulling_force_interaction(const toml::value& external); diff --git a/mjolnir/input/read_external_interaction.hpp b/mjolnir/input/read_external_interaction.hpp index 790a7e8f8..25ab65508 100644 --- a/mjolnir/input/read_external_interaction.hpp +++ b/mjolnir/input/read_external_interaction.hpp @@ -22,81 +22,28 @@ namespace mjolnir // external interaction // ---------------------------------------------------------------------------- -template +template std::unique_ptr> -read_external_distance_interaction(const toml::value& external, shapeT&& shape) +read_external_distance_interaction_shape( + const toml::value& external, potentialT&& pot, const bool read_margin = true) { MJOLNIR_GET_DEFAULT_LOGGER(); MJOLNIR_LOG_FUNCTION(); - using real_type = typename traitsT::real_type; - - const auto potential = toml::find(external, "potential"); - if(potential == "ImplicitMembrane") - { - MJOLNIR_LOG_NOTICE("-- potential function is Implicit Membrane."); - using potential_t = ImplicitMembranePotential; - using interaction_t = ExternalDistanceInteraction< - traitsT, potential_t, shapeT>; - - return make_unique(std::move(shape), - read_implicit_membrane_potential(external)); - } - else if(potential == "LennardJonesWall") - { - MJOLNIR_LOG_NOTICE("-- potential function is Lennard-Jones."); - using potential_t = LennardJonesWallPotential; - using interaction_t = ExternalDistanceInteraction< - traitsT, potential_t, shapeT>; - return make_unique(std::move(shape), - read_lennard_jones_wall_potential(external)); - } - else if(potential == "ExcludedVolumeWall") - { - MJOLNIR_LOG_NOTICE("-- potential function is Excluded-Volume."); - using potential_t = ExcludedVolumeWallPotential; - using interaction_t = ExternalDistanceInteraction< - traitsT, potential_t, shapeT>; - return make_unique(std::move(shape), - read_excluded_volume_wall_potential(external)); - } - else if(potential == "HarmonicGroove") - { - MJOLNIR_LOG_NOTICE("-- potential function is Harmonic."); - using potential_t = HarmonicGroovePotential; - using interaction_t = ExternalDistanceInteraction< - traitsT, potential_t, shapeT>; - return make_unique(std::move(shape), - read_harmonic_groove_potential(external)); - } - else - { - throw_exception(toml::format_error("[error] " - "mjolnir::read_external_distance_interaction: invalid potential", - toml::find(external, "potential"), "here", { - "expected value is one of the following.", - "- \"HarmonicGroove\" : attractive r^2 potential", - "- \"ExcludedVolumeWall\": repulsive r^12 potential", - "- \"LennardJonesWall\" : famous r^12 - r^6 potential", - "- \"ImplicitMembrane\" : single-well interaction that models a membrane" - })); - } -} - -template -std::unique_ptr> -read_external_distance_interaction_shape(const toml::value& external) -{ - MJOLNIR_GET_DEFAULT_LOGGER(); - MJOLNIR_LOG_FUNCTION(); - using real_type = typename traitsT::real_type; const auto shape = toml::find(external, "shape"); const auto name = toml::find(shape, "name"); + using real_type = typename traitsT::real_type; + if(name == "AxisAlignedPlane") { const auto pos = toml::find(shape, "position"); - const auto margin = toml::find(shape, "margin"); + real_type margin = std::numeric_limits::infinity(); + if(read_margin) + { + margin = toml::find(shape, "margin"); + } + MJOLNIR_LOG_INFO("pos = ", pos); MJOLNIR_LOG_INFO("margin = ", margin); @@ -107,44 +54,49 @@ read_external_distance_interaction_shape(const toml::value& external) { MJOLNIR_LOG_NOTICE("-- interaction shape is YZ-Plane (+)."); using shape_t = AxisAlignedPlane>; - - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else if(axis == "-X") { MJOLNIR_LOG_NOTICE("-- interaction shape is YZ-Plane (-)."); using shape_t = AxisAlignedPlane>; - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else if(axis == "Y" || axis == "+Y") { MJOLNIR_LOG_NOTICE("-- interaction shape is ZX-Plane (+)."); using shape_t = AxisAlignedPlane>; - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else if(axis == "-Y") { MJOLNIR_LOG_NOTICE("-- interaction shape is ZX-Plane (-)."); using shape_t = AxisAlignedPlane>; - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else if(axis == "Z" || axis == "+Z") { MJOLNIR_LOG_NOTICE("-- interaction shape is XY-Plane (+)."); using shape_t = AxisAlignedPlane>; - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else if(axis == "-Z") { MJOLNIR_LOG_NOTICE("-- interaction shape is XY-Plane (-)."); using shape_t = AxisAlignedPlane>; - return read_external_distance_interaction( - external, shape_t(pos, margin)); + using interaction_t = ExternalDistanceInteraction< + traitsT, potentialT, shape_t>; + return make_unique(shape_t(pos, margin), std::move(pot)); } else { @@ -157,8 +109,61 @@ read_external_distance_interaction_shape(const toml::value& external) { throw std::runtime_error("invalid external forcefield shape: " + name); } + +} + +template +std::unique_ptr> +read_external_distance_interaction(const toml::value& external) +{ + MJOLNIR_GET_DEFAULT_LOGGER(); + MJOLNIR_LOG_FUNCTION(); + using real_type = typename traitsT::real_type; + + const auto potential = toml::find(external, "potential"); + if(potential == "ImplicitMembrane") + { + MJOLNIR_LOG_NOTICE("-- potential function is Implicit Membrane."); + using potential_t = ImplicitMembranePotential; + return read_external_distance_interaction_shape( + external, read_implicit_membrane_potential(external)); + } + else if(potential == "LennardJonesWall") + { + MJOLNIR_LOG_NOTICE("-- potential function is Lennard-Jones."); + using potential_t = LennardJonesWallPotential; + return read_external_distance_interaction_shape( + external, read_lennard_jones_wall_potential(external)); + } + else if(potential == "ExcludedVolumeWall") + { + MJOLNIR_LOG_NOTICE("-- potential function is Excluded-Volume."); + using potential_t = ExcludedVolumeWallPotential; + return read_external_distance_interaction_shape( + external, read_excluded_volume_wall_potential(external)); + } + else if(potential == "HarmonicGroove") + { + MJOLNIR_LOG_NOTICE("-- potential function is Harmonic."); + using potential_t = HarmonicGroovePotential; + return read_external_distance_interaction_shape( + external, read_harmonic_groove_potential(external), false); + } + else + { + throw_exception(toml::format_error("[error] " + "mjolnir::read_external_distance_interaction: invalid potential", + toml::find(external, "potential"), "here", { + "expected value is one of the following.", + "- \"HarmonicGroove\" : attractive r^2 potential", + "- \"ExcludedVolumeWall\": repulsive r^12 potential", + "- \"LennardJonesWall\" : famous r^12 - r^6 potential", + "- \"ImplicitMembrane\" : single-well interaction that models a membrane" + })); + } } + template std::unique_ptr> read_external_position_restraint_interaction(const toml::value& external) @@ -448,7 +453,7 @@ read_external_interaction(const toml::value& external) if(interaction == "Distance") { MJOLNIR_LOG_NOTICE("Distance interaction found."); - return read_external_distance_interaction_shape(external); + return read_external_distance_interaction(external); } else if(interaction == "PositionRestraint") { @@ -512,10 +517,10 @@ extern template std::unique_ptr>> read_afm_flexible_fitting_interaction(const toml::value&); extern template std::unique_ptr>> read_afm_flexible_fitting_interaction(const toml::value&); -extern template std::unique_ptr >> read_external_distance_interaction_shape(const toml::value& external); -extern template std::unique_ptr >> read_external_distance_interaction_shape(const toml::value& external); -extern template std::unique_ptr>> read_external_distance_interaction_shape(const toml::value& external); -extern template std::unique_ptr>> read_external_distance_interaction_shape(const toml::value& external); +extern template std::unique_ptr >> read_external_distance_interaction(const toml::value& external); +extern template std::unique_ptr >> read_external_distance_interaction(const toml::value& external); +extern template std::unique_ptr>> read_external_distance_interaction(const toml::value& external); +extern template std::unique_ptr>> read_external_distance_interaction(const toml::value& external); #endif } // mjolnir