From c4b26405de7686334c95e7e051ab8fe95d2e7db5 Mon Sep 17 00:00:00 2001 From: Julian Hossbach Date: Wed, 24 Aug 2022 14:10:45 +0200 Subject: [PATCH] Rewrite LJcos interaction interface --- src/core/nonbonded_interactions/ljcos.cpp | 42 ++++++------- src/core/nonbonded_interactions/ljcos.hpp | 3 - .../nonbonded_interaction_data.hpp | 4 ++ src/python/espressomd/interactions.pxd | 14 ----- src/python/espressomd/interactions.pyx | 61 +++++++------------ .../interactions/NonBondedInteraction.hpp | 46 ++++++++++++++ .../interactions/initialize.cpp | 3 + 7 files changed, 94 insertions(+), 79 deletions(-) diff --git a/src/core/nonbonded_interactions/ljcos.cpp b/src/core/nonbonded_interactions/ljcos.cpp index 78c29d28a80..84d204c9c57 100644 --- a/src/core/nonbonded_interactions/ljcos.cpp +++ b/src/core/nonbonded_interactions/ljcos.cpp @@ -25,34 +25,32 @@ #include "ljcos.hpp" #ifdef LJCOS -#include "interactions.hpp" #include "nonbonded_interaction_data.hpp" #include #include -int ljcos_set_params(int part_type_a, int part_type_b, double eps, double sig, - double cut, double offset) { - IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) - return ES_ERROR; - - data->ljcos.eps = eps; - data->ljcos.sig = sig; - data->ljcos.cut = cut; - data->ljcos.offset = offset; - - /* Calculate dependent parameters */ +LJcos_Parameters::LJcos_Parameters(double eps, double sig, double cut, + double offset) + : LJcos_Parameters(eps, sig, cut, offset, 0., 0., 0.) { auto const facsq = Utils::cbrt_2() * Utils::sqr(sig); - data->ljcos.rmin = sqrt(Utils::cbrt_2()) * sig; - data->ljcos.alfa = Utils::pi() / (Utils::sqr(data->ljcos.cut) - facsq); - data->ljcos.beta = - Utils::pi() * (1. - (1. / (Utils::sqr(data->ljcos.cut) / facsq - 1.))); - /* broadcast interaction parameters */ - mpi_bcast_ia_params(part_type_a, part_type_b); + rmin = sqrt(Utils::cbrt_2()) * sig; + alfa = Utils::pi() / (Utils::sqr(cut) - facsq); + beta = Utils::pi() * (1. - (1. / (Utils::sqr(cut) / facsq - 1.))); +} - return ES_OK; +LJcos_Parameters::LJcos_Parameters(double eps, double sig, double cut, + double offset, double alfa, double beta, + double rmin) + : eps{eps}, sig{sig}, cut{cut}, offset{offset}, alfa{alfa}, beta{beta}, + rmin{rmin} { + if (eps < 0.) { + std::domain_error("Lennard-Jones parameter 'epsilon' has to be >= 0"); + } + if (sig < 0.) { + std::domain_error("Lennard-Jones parameter 'sigma' has to be >= 0"); + } } -#endif + +#endif // LJCOS diff --git a/src/core/nonbonded_interactions/ljcos.hpp b/src/core/nonbonded_interactions/ljcos.hpp index 342c08c99c6..b803a952aa0 100644 --- a/src/core/nonbonded_interactions/ljcos.hpp +++ b/src/core/nonbonded_interactions/ljcos.hpp @@ -39,9 +39,6 @@ #include -int ljcos_set_params(int part_type_a, int part_type_b, double eps, double sig, - double cut, double offset); - /** Calculate Lennard-Jones cosine force factor */ inline double ljcos_pair_force_factor(IA_parameters const &ia_params, double dist) { diff --git a/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp b/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp index 2942ecbb587..1608af8dd92 100644 --- a/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp +++ b/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp @@ -157,6 +157,10 @@ struct LJcos_Parameters { double alfa = 0.0; double beta = 0.0; double rmin = 0.0; + LJcos_Parameters() = default; + LJcos_Parameters(double eps, double sig, double cut, double offset); + LJcos_Parameters(double eps, double sig, double cut, double offset, + double alfa, double beta, double rmin); }; /** Lennard-Jones with a different Cos potential */ diff --git a/src/python/espressomd/interactions.pxd b/src/python/espressomd/interactions.pxd index 6fd9f585b22..99a3c1cb61a 100644 --- a/src/python/espressomd/interactions.pxd +++ b/src/python/espressomd/interactions.pxd @@ -106,12 +106,6 @@ cdef extern from "nonbonded_interactions/nonbonded_interaction_data.hpp": double Fmax double r - cdef struct LJcos_Parameters: - double eps - double sig - double cut - double offset - cdef struct LJcos2_Parameters: double eps double sig @@ -140,8 +134,6 @@ cdef extern from "nonbonded_interactions/nonbonded_interaction_data.hpp": cdef struct IA_parameters: - LJcos_Parameters ljcos - LJcos2_Parameters ljcos2 LJGen_Parameters ljgen @@ -176,12 +168,6 @@ cdef extern from "nonbonded_interactions/nonbonded_interaction_data.hpp": cdef void ia_params_set_state(string) cdef void reset_ia_params() -IF LJCOS: - cdef extern from "nonbonded_interactions/ljcos.hpp": - cdef int ljcos_set_params(int part_type_a, int part_type_b, - double eps, double sig, - double cut, double offset) - IF LJCOS2: cdef extern from "nonbonded_interactions/ljcos2.hpp": cdef int ljcos2_set_params(int part_type_a, int part_type_b, diff --git a/src/python/espressomd/interactions.pyx b/src/python/espressomd/interactions.pyx index 5baf123a894..38439681dc3 100644 --- a/src/python/espressomd/interactions.pyx +++ b/src/python/espressomd/interactions.pyx @@ -559,37 +559,22 @@ IF LENNARD_JONES_GENERIC == 1: return {"epsilon", "sigma", "cutoff", "shift", "offset", "e1", "e2", "b1", "b2"} -IF LJCOS: +IF LJCOS == 1: - cdef class LennardJonesCosInteraction(NonBondedInteraction): - - def validate_params(self): - if self._params["epsilon"] < 0: - raise ValueError("Lennard-Jones epsilon has to be >=0") - if self._params["sigma"] < 0: - raise ValueError("Lennard-Jones sigma has to be >=0") - - def _get_params_from_es_core(self): - cdef IA_parameters * ia_params - ia_params = get_ia_param_safe( - self._part_types[0], - self._part_types[1]) - return { - "epsilon": ia_params.ljcos.eps, - "sigma": ia_params.ljcos.sig, - "cutoff": ia_params.ljcos.cut, - "offset": ia_params.ljcos.offset, - } - - def is_active(self): - return(self._params["epsilon"] > 0) + @script_interface_register + class LennardJonesCosInteraction(NewNonBondedInteraction): + """Lennard-Jones cosine interaction. - def set_params(self, **kwargs): - """Set parameters for the Lennard-Jones cosine interaction. + Methods + ------- + set_params() + Set or update parameters for the interaction. + Parameters marked as required become optional once the + interaction has been activated for the first time; + subsequent calls to this method update the existing values. Parameters ---------- - epsilon : :obj:`float` Magnitude of the interaction. sigma : :obj:`float` @@ -598,18 +583,15 @@ IF LJCOS: Cutoff distance of the interaction. offset : :obj:`float`, optional Offset distance of the interaction. - """ - super().set_params(**kwargs) + """ - def _set_params_in_es_core(self): - if ljcos_set_params(self._part_types[0], - self._part_types[1], - self._params["epsilon"], - self._params["sigma"], - self._params["cutoff"], - self._params["offset"]): - raise Exception( - "Could not set Lennard-Jones Cosine parameters") + _so_name = "Interactions::InteractionLJcos" + + def is_active(self): + """Check if interactions is active. + + """ + return self.epsilon > 0. def default_params(self): return {"offset": 0.} @@ -624,7 +606,8 @@ IF LJCOS: """All parameters that can be set. """ - return {"epsilon", "sigma", "cutoff", "offset"} + return {"epsilon", "sigma", "cutoff", + "offset", "alfa", "beta", "rmin"} def required_keys(self): """Parameters that have to be set. @@ -1578,8 +1561,6 @@ class NonBondedInteractionHandle(ScriptInterfaceHelper): IF LENNARD_JONES_GENERIC: self.generic_lennard_jones = GenericLennardJonesInteraction( _type1, _type2) - IF LJCOS: - self.lennard_jones_cos = LennardJonesCosInteraction(_type1, _type2) IF LJCOS2: self.lennard_jones_cos2 = LennardJonesCos2Interaction( _type1, _type2) diff --git a/src/script_interface/interactions/NonBondedInteraction.hpp b/src/script_interface/interactions/NonBondedInteraction.hpp index 99ca6eeb6ad..a7fedddd1dd 100644 --- a/src/script_interface/interactions/NonBondedInteraction.hpp +++ b/src/script_interface/interactions/NonBondedInteraction.hpp @@ -191,6 +191,42 @@ class InteractionLJ : public InteractionPotentialInterface<::LJ_Parameters> { }; #endif // LENNARD_JONES +#ifdef LJCOS +class InteractionLJcos + : public InteractionPotentialInterface<::LJcos_Parameters> { +protected: + CoreInteraction IA_parameters::*get_ptr_offset() const override { + return &::IA_parameters::ljcos; + } + +public: + InteractionLJcos() { + add_parameters({ + make_autoparameter(&CoreInteraction::eps, "epsilon"), + make_autoparameter(&CoreInteraction::sig, "sigma"), + make_autoparameter(&CoreInteraction::cut, "cutoff"), + make_autoparameter(&CoreInteraction::offset, "offset"), + make_autoparameter(&CoreInteraction::alfa, "alfa"), + make_autoparameter(&CoreInteraction::beta, "beta"), + make_autoparameter(&CoreInteraction::rmin, "rmin"), + }); + } + + void make_new_instance(VariantMap const ¶ms) override { + if (boost::get(¶ms.at("alfa"))) { + m_ia_si = make_shared_from_args( + params, "epsilon", "sigma", "cutoff", "offset", "alfa", "beta", + "rmin"); + } else { + m_ia_si = make_shared_from_args(params, "epsilon", "sigma", + "cutoff", "offset"); + } + } +}; +#endif // LJCOS + class NonBondedInteractionHandle : public AutoParameters { std::array m_types = {-1, -1}; @@ -201,6 +237,9 @@ class NonBondedInteractionHandle #ifdef LENNARD_JONES std::shared_ptr m_lj; #endif +#ifdef LJCOS + std::shared_ptr m_ljcos; +#endif template auto make_autoparameter(std::shared_ptr &member, const char *key) const { @@ -224,6 +263,9 @@ class NonBondedInteractionHandle #endif #ifdef LENNARD_JONES make_autoparameter(m_lj, "lennard_jones"), +#endif +#ifdef LJCOS + make_autoparameter(m_ljcos, "lennard_jones_cos"), #endif }); } @@ -270,6 +312,10 @@ class NonBondedInteractionHandle #ifdef LENNARD_JONES set_member(m_lj, "lennard_jones", "Interactions::InteractionLJ", params); +#endif +#ifdef LJCOS + set_member(m_ljcos, "lennard_jones_cos", + "Interactions::InteractionLJcos", params); #endif } diff --git a/src/script_interface/interactions/initialize.cpp b/src/script_interface/interactions/initialize.cpp index 03bba64c9ea..2c5e0e60639 100644 --- a/src/script_interface/interactions/initialize.cpp +++ b/src/script_interface/interactions/initialize.cpp @@ -59,6 +59,9 @@ void initialize(Utils::Factory *om) { #ifdef LENNARD_JONES om->register_new("Interactions::InteractionLJ"); #endif +#ifdef LJCOS + om->register_new("Interactions::InteractionLJcos"); +#endif #ifdef WCA om->register_new("Interactions::InteractionWCA"); #endif