ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
NonBondedInteractions.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
23
26
29
31
32#include <cassert>
33#include <memory>
34#include <stdexcept>
35#include <string>
36#include <unordered_map>
37#include <utility>
38#include <vector>
39
40namespace ScriptInterface {
41namespace Interactions {
42
44public:
45 using key_type = unsigned int;
46 using mapped_type = std::shared_ptr<NonBondedInteractionHandle>;
47
48private:
49 using container_type = std::unordered_map<key_type, mapped_type>;
50 container_type m_nonbonded_ia_params;
51 std::shared_ptr<::InteractionsNonBonded> m_handle;
52 std::shared_ptr<std::function<void()>> m_notify_cutoff_change;
53
54public:
55 ~NonBondedInteractions() override = default;
56
57 void do_construct(VariantMap const &params) override {
58 m_handle = std::make_shared<::InteractionsNonBonded>();
59 m_notify_cutoff_change = std::make_shared<std::function<void()>>([]() {});
60 }
61
62private:
64 auto const max_type = m_handle->get_max_seen_particle_type();
65 system.nonbonded_ias = m_handle;
66 m_handle->make_particle_type_exist(max_type);
67 m_handle->bind_system(m_system.lock());
68 m_handle->on_non_bonded_ia_change();
69 *m_notify_cutoff_change = [this]() {
70 if (m_handle and not m_system.expired()) {
71 m_handle->on_non_bonded_ia_change();
72 }
73 };
74 }
75
76 std::pair<int, int> get_key(Variant const &key) const {
77 try {
79 if (types.size() != 2ul or types[0] < 0 or types[1] < 0) {
80 throw Exception("need two particle types");
81 }
82 return {std::min(types[0], types[1]), std::max(types[0], types[1])};
83 } catch (...) {
84 if (context()->is_head_node()) {
85 throw std::invalid_argument(
86 "NonBondedInteractions[] expects two particle types as indices");
87 }
88 throw;
89 }
90 }
91
92public:
93 Variant do_call_method(std::string const &method,
94 VariantMap const &params) override {
95 if (method == "reset") {
96 if (not context()->is_head_node()) {
97 return {};
98 }
99 auto const max_type = m_handle->get_max_seen_particle_type();
100 auto const obj_params = VariantMap{{"notify", false}};
101 for (int i = 0; i <= max_type; i++) {
102 for (int j = 0; j <= i; j++) {
103 auto const key = m_handle->get_ia_param_key(i, j);
104 if (m_nonbonded_ia_params.contains(key)) {
105 m_nonbonded_ia_params.at(key)->call_method("reset", obj_params);
106 }
107 }
108 }
109 call_method("internal_global_on_non_bonded_ia_change", {});
110 return {};
111 }
112 if (method == "get_handle") {
113 auto ctx = context();
114 auto const [type_min, type_max] = get_key(params.at("key"));
115 if (type_max > m_handle->get_max_seen_particle_type()) {
116 m_handle->make_particle_type_exist(type_max);
117 }
118 if (not ctx->is_head_node()) {
119 return {};
120 }
121 auto const key = m_handle->get_ia_param_key(type_min, type_max);
122 if (m_nonbonded_ia_params.contains(key)) {
123 return m_nonbonded_ia_params.at(key);
124 }
125 auto so = std::dynamic_pointer_cast<NonBondedInteractionHandle>(
126 ctx->make_shared("Interactions::NonBondedInteractionHandle", {}));
127 m_nonbonded_ia_params[key] = so;
128 call_method("internal_attach", {{"key", params.at("key")}, {"obj", so}});
129 return so;
130 }
131 if (method == "internal_set_max_type") {
132 m_handle->make_particle_type_exist(get_value<int>(params, "max_type"));
133 return {};
134 }
135 if (method == "internal_attach") {
136 auto so = std::dynamic_pointer_cast<NonBondedInteractionHandle>(
138 auto const [i, j] = get_key(params.at("key"));
139 auto const cb_register =
140 [this, i, j](std::shared_ptr<::IA_parameters> const &core_ia) {
141 m_handle->set_ia_param(i, j, core_ia);
142 };
143 so->attach(cb_register, m_notify_cutoff_change);
144 return {};
145 }
146 if (method == "internal_global_on_non_bonded_ia_change") {
147 get_system().on_non_bonded_ia_change();
148 return {};
149 }
150
151 return {};
152 }
153
154private:
155 std::string get_internal_state() const override {
156 auto const max_type = m_handle->get_max_seen_particle_type();
157 std::vector<std::string> object_states;
158 object_states.emplace_back(Utils::pack(max_type));
159 for (int i = 0; i <= max_type; i++) {
160 for (int j = 0; j <= i; j++) {
161 auto const key = m_handle->get_ia_param_key(i, j);
162 if (m_nonbonded_ia_params.contains(key)) {
163 object_states.emplace_back(
164 m_nonbonded_ia_params.at(key)->serialize());
165 } else {
166 object_states.emplace_back("");
167 }
168 }
169 }
170
172 }
173
174 void set_internal_state(std::string const &state) override {
175 auto const object_states = Utils::unpack<std::vector<std::string>>(state);
176 auto const max_type = Utils::unpack<int>(object_states.front());
177 call_method("internal_set_max_type", {{"max_type", max_type}});
178 auto const end = object_states.end();
179 auto it = object_states.begin() + 1;
180 for (int i = 0; i <= max_type; i++) {
181 for (int j = 0; j <= i; j++) {
182 auto const key = m_handle->get_ia_param_key(i, j);
183 auto const &buffer = *it;
184 if (not buffer.empty()) {
185 auto so = std::dynamic_pointer_cast<NonBondedInteractionHandle>(
187 m_nonbonded_ia_params[key] = so;
188 call_method("internal_attach",
189 {{"key", std::vector<int>{{j, i}}}, {"obj", so}});
190 }
191 ++it;
192 if (it == end) {
193 break;
194 }
195 }
196 }
197 }
198};
199
200} // namespace Interactions
201} // namespace ScriptInterface
The ScriptInterface counterparts of the non-bonded interactions parameters structs from the core are ...
void set_internal_state(std::string const &state) override
void on_bind_system(::System::System &system) override
void do_construct(VariantMap const &params) override
std::shared_ptr< NonBondedInteractionHandle > mapped_type
Variant do_call_method(std::string const &method, VariantMap const &params) override
Variant call_method(const std::string &name, const VariantMap &params)
Call a method on the object.
Context * context() const
Responsible context.
static ObjectRef deserialize(const std::string &state, Context &ctx)
Make object from serialized state.
Script interface wrapper for a component of the system class.
std::weak_ptr<::System::System > m_system
Main system class.
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:69
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectRef, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type Variant
Possible types for parameters.
Definition Variant.hpp:67
std::string pack(T const &v)
Pack a serialize type into a string.
Definition pack.hpp:38
Various procedures concerning interactions between particles.
static SteepestDescentParameters params
Currently active steepest descent instance.