Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
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.