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
LeesEdwards.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
22#include "Protocol.hpp"
23
24#include "core/BoxGeometry.hpp"
27
31
32#include <memory>
33#include <stdexcept>
34
35namespace ScriptInterface {
36namespace LeesEdwards {
37
38class LeesEdwards : public AutoParameters<LeesEdwards, System::Leaf> {
39 std::shared_ptr<::LeesEdwards::LeesEdwards> m_lees_edwards;
40 std::shared_ptr<Protocol> m_protocol;
41 std::unique_ptr<VariantMap> m_params;
42
43public:
46 {{"protocol",
47 [this](Variant const &value) {
48 auto &system = get_system();
49 if (is_none(value)) {
51 auto constexpr invalid_dir = LeesEdwardsBC::invalid_dir;
52 system.lb.lebc_sanity_checks(invalid_dir, invalid_dir);
53 });
54 m_protocol = nullptr;
55 system.box_geo->set_lees_edwards_bc(LeesEdwardsBC{});
56 m_lees_edwards->unset_protocol();
57 system.on_lees_edwards_change();
58 return;
59 }
60 context()->parallel_try_catch([this]() {
61 auto constexpr invalid_dir = LeesEdwardsBC::invalid_dir;
62 auto const &lebc = get_lebc();
63 if (lebc.shear_direction == invalid_dir or
64 lebc.shear_plane_normal == invalid_dir) {
65 throw std::runtime_error(
66 "Parameters 'shear_plane_normal' and 'shear_direction' "
67 "must be initialized together with 'protocol' on first "
68 "activation via set_boundary_conditions()");
69 }
70 });
71 auto const protocol = get_value<std::shared_ptr<Protocol>>(value);
73 try {
74 set_protocol(protocol);
75 } catch (...) {
76 set_protocol(m_protocol);
77 throw;
78 }
79 });
80 },
81 [this]() {
82 if (m_protocol)
83 return make_variant(m_protocol);
84 return make_variant(none);
85 }},
86 {"shear_velocity", AutoParameter::read_only,
87 [this]() { return get_lebc().shear_velocity; }},
88 {"pos_offset", AutoParameter::read_only,
89 [this]() { return get_lebc().pos_offset; }},
90 {"shear_direction", AutoParameter::read_only,
91 [this]() { return get_shear_name(get_lebc().shear_direction); }},
92 {"shear_plane_normal", AutoParameter::read_only,
93 [this]() { return get_shear_name(get_lebc().shear_plane_normal); }}});
94 }
95
96 Variant do_call_method(std::string const &name,
97 VariantMap const &params) override {
98 if (name == "set_boundary_conditions") {
99 context()->parallel_try_catch([this, &params]() {
100 auto const variant = params.at("protocol");
101 if (is_none(variant)) {
102 do_set_parameter("protocol", variant);
103 return;
104 }
105 // check input arguments
106 auto const protocol = get_value<std::shared_ptr<Protocol>>(variant);
107 auto const shear_direction = get_shear_axis(params, "shear_direction");
108 auto const shear_plane_normal =
109 get_shear_axis(params, "shear_plane_normal");
110 if (shear_plane_normal == shear_direction) {
111 throw std::invalid_argument("Parameters 'shear_direction' and "
112 "'shear_plane_normal' must differ");
113 }
114 auto &system = get_system();
115 system.lb.lebc_sanity_checks(shear_direction, shear_plane_normal);
116 // update box geometry and cell structure
117 auto const old_shear_direction = get_lebc().shear_direction;
118 auto const old_shear_plane_normal = get_lebc().shear_plane_normal;
119 try {
120 system.box_geo->set_lees_edwards_bc(
121 LeesEdwardsBC{0., 0., shear_direction, shear_plane_normal});
122 set_protocol(protocol);
123 } catch (...) {
124 system.box_geo->set_lees_edwards_bc(LeesEdwardsBC{
126 set_protocol(m_protocol);
127 throw;
128 }
129 });
130 }
131 return {};
132 }
133
134 void do_construct(VariantMap const &params) override {
135 m_params = std::make_unique<VariantMap>(params);
136 }
137
138private:
139 unsigned int get_shear_axis(VariantMap const &params, std::string name) {
140 auto const value = get_value<std::string>(params, name);
141 if (value == "x") {
142 return 0u;
143 }
144 if (value == "y") {
145 return 1u;
146 }
147 if (value == "z") {
148 return 2u;
149 }
150 throw std::invalid_argument("Parameter '" + name + "' is invalid");
151 }
152
153 Variant get_shear_name(unsigned int axis) {
154 if (axis == 0u) {
155 return {std::string("x")};
156 }
157 if (axis == 1u) {
158 return {std::string("y")};
159 }
160 if (axis == 2u) {
161 return {std::string("z")};
162 }
163 return {none};
164 }
165
166 LeesEdwardsBC const &get_lebc() const {
167 return get_system().box_geo->lees_edwards_bc();
168 }
169
171 m_lees_edwards = system.lees_edwards;
172 auto const &params = *m_params;
173 if (not params.empty()) {
174 do_call_method("set_boundary_conditions", params);
175 }
176 m_params.reset();
177 }
178
179 void set_protocol(std::shared_ptr<Protocol> const &protocol) {
180 auto &system = get_system();
181 if (protocol) {
182 m_lees_edwards->set_protocol(protocol->protocol());
183 } else {
184 system.box_geo->set_lees_edwards_bc(LeesEdwardsBC{});
185 m_lees_edwards->unset_protocol();
186 }
187 system.on_lees_edwards_change();
188 m_protocol = protocol;
189 }
190};
191
192} // namespace LeesEdwards
193} // namespace ScriptInterface
Bind parameters in the script interface.
void do_set_parameter(const std::string &name, const Variant &value) final
void add_parameters(std::vector< AutoParameter > &&params)
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
Variant do_call_method(std::string const &name, VariantMap const &params) override
void do_construct(VariantMap const &params) override
void on_bind_system(::System::System &system) override
boost::string_ref name() const
Context * context() const
Responsible context.
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
Variant make_variant(const T &x)
Make a Variant from argument.
Definition Variant.hpp:77
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
bool is_none(Variant const &v)
Definition Variant.hpp:115
constexpr const None none
None-"literal".
Definition Variant.hpp:50
static SteepestDescentParameters params
Currently active steepest descent instance.
static auto constexpr invalid_dir
unsigned int shear_plane_normal
unsigned int shear_direction
static constexpr const ReadOnly read_only