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
30
32
33#include <cassert>
34#include <memory>
35#include <stdexcept>
36#include <string>
37#include <unordered_map>
38#include <utility>
39#include <vector>
40
41namespace ScriptInterface {
42namespace Interactions {
43
45 using container_type =
46 std::unordered_map<unsigned int,
47 std::shared_ptr<NonBondedInteractionHandle>>;
48
49public:
50 using key_type = typename container_type::key_type;
51 using mapped_type = typename container_type::mapped_type;
52
53private:
54 container_type m_nonbonded_ia_params;
55 std::shared_ptr<::InteractionsNonBonded> m_handle;
56 std::shared_ptr<std::function<void()>> m_notify_cutoff_change;
57
58 void do_construct(VariantMap const &params) override {
59 m_handle = std::make_shared<::InteractionsNonBonded>();
60 m_notify_cutoff_change = std::make_shared<std::function<void()>>([]() {});
61 }
62
63 void on_bind_system(::System::System &system) override {
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 {
78 auto const types = get_value<std::vector<int>>(key);
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
92protected:
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 get_system().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>(
137 get_value<ObjectRef>(params, "obj"));
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
147 return {};
148 }
149
150 std::string get_internal_state() const override {
151 auto const max_type = m_handle->get_max_seen_particle_type();
152 std::vector<std::string> object_states;
153 object_states.emplace_back(Utils::pack(max_type));
154 for (int i = 0; i <= max_type; i++) {
155 for (int j = 0; j <= i; j++) {
156 auto const key = m_handle->get_ia_param_key(i, j);
157 if (m_nonbonded_ia_params.contains(key)) {
158 object_states.emplace_back(
159 m_nonbonded_ia_params.at(key)->serialize());
160 } else {
161 object_states.emplace_back("");
162 }
163 }
164 }
165
166 return Utils::pack(object_states);
167 }
168
169 void set_internal_state(std::string const &state) override {
170 auto const object_states = Utils::unpack<std::vector<std::string>>(state);
171 auto const max_type = Utils::unpack<int>(object_states.front());
172 call_method("internal_set_max_type", {{"max_type", max_type}});
173 auto const end = object_states.end();
174 auto it = object_states.begin() + 1;
175 for (int i = 0; i <= max_type; i++) {
176 for (int j = 0; j <= i; j++) {
177 auto const key = m_handle->get_ia_param_key(i, j);
178 auto const &buffer = *it;
179 if (not buffer.empty()) {
180 auto so = std::dynamic_pointer_cast<NonBondedInteractionHandle>(
182 m_nonbonded_ia_params[key] = so;
183 call_method("internal_attach",
184 {{"key", std::vector<int>{{j, i}}}, {"obj", so}});
185 }
186 ++it;
187 if (it == end) {
188 break;
189 }
190 }
191 }
192 }
193};
194
195} // namespace Interactions
196} // 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
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.
std::shared_ptr< InteractionsNonBonded > nonbonded_ias
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.