ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
script_interface/thermostat/thermostat.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023-2026 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
24#include "core/thermostat.hpp"
25
29#ifdef ESPRESSO_WALBERLA
31#endif
32
33#include <cassert>
34#include <cstdint>
35#include <limits>
36#include <memory>
37#include <span>
38#include <stdexcept>
39#include <string>
40
41namespace ScriptInterface {
42namespace Thermostat {
43
44template <typename CoreClass>
45class Interface : public AutoParameters<Interface<CoreClass>, System::Leaf> {
47
48public:
49 using CoreThermostat = CoreClass;
53
54protected:
59
60 bool is_active = false;
61 std::shared_ptr<CoreThermostat> m_handle;
62 /** @brief Basic lock mechanism that follows RAII. */
63 std::weak_ptr<bool> m_edit_lock;
64
65 void check_lock() {
66 if (m_edit_lock.expired()) {
68 }
69 }
70
72 get_member_handle(*system.thermostat) = m_handle;
73 system.on_thermostat_param_change();
74 is_active = true;
75 }
76
78 get_member_handle(*system.thermostat).reset();
79 system.on_thermostat_param_change();
80 is_active = false;
81 }
82
83 void sanity_checks_positive(double value, std::string const &name) const {
84 if (value < 0.) {
85 throw std::domain_error("Parameter '" + name + "' cannot be negative");
86 }
87 }
88
90 std::string const &name) const {
91 if (not(value >= Utils::Vector3d::broadcast(0.))) {
92 throw std::domain_error("Parameter '" + name + "' cannot be negative");
93 }
94 }
95
96 virtual bool invalid_rng_state(VariantMap const &params) const {
97 return (not params.contains("seed") or is_none(params.at("seed"))) and
99 }
100
101private:
102 virtual std::shared_ptr<CoreThermostat> &
104
105 void set_new_parameters(VariantMap const &params) {
106 context()->parallel_try_catch([&]() {
107 if (params.contains("__check_rng_state") and invalid_rng_state(params)) {
108 throw std::invalid_argument("Parameter 'seed' is needed on first "
109 "activation of the thermostat");
110 }
111 check_required_parameters(params);
112 });
113 for (auto const &key : get_parameter_insertion_order()) {
114 if (params.contains(key)) {
115 auto const &v = params.at(key);
116 if (key == "is_active") {
118 } else {
119 do_set_parameter(key.c_str(), v);
120 }
121 }
122 }
123 }
124
125 virtual std::span<std::string_view const> get_required_parameters() const = 0;
126
127 void check_required_parameters(VariantMap const &params) const {
128 for (auto const &required : get_required_parameters()) {
129 auto name = std::string(required);
130 if (not params.contains(name)) {
131 throw std::runtime_error("Parameter '" + name + "' is missing");
132 }
133 }
134 }
135
136protected:
137 template <typename T>
139 return AutoParameter{
140 name,
141 [this, member, name = std::string(name)](Variant const &v) {
142 check_lock();
143 auto const value = get_value<T>(v);
145 [&]() { sanity_checks_positive(value, name); });
146 m_handle.get()->*member = std::move(value);
147 },
148 [this, member]() { return m_handle.get()->*member; }};
149 }
150
151 template <typename T>
153 return AutoParameter{
154 name,
155 [this, member, name = std::string(name)](Variant const &v) {
156 check_lock();
157 if (is_none(v)) {
158 return;
159 }
160#ifdef ESPRESSO_PARTICLE_ANISOTROPY
161 static_assert(std::is_same_v<T, Utils::Vector3d>);
162 T gamma{};
163 if (is_type<int>(v) or is_type<double>(v)) {
164 gamma = T::broadcast(get_value<double>(v));
165 } else {
166 gamma = get_value<T>(v);
167 }
168#else
169 auto const gamma = get_value<T>(v);
170#endif // ESPRESSO_PARTICLE_ANISOTROPY
172 [&]() { sanity_checks_positive(gamma, name); });
173 m_handle.get()->*member = gamma;
174 },
175 [this, member]() {
176 auto constexpr gamma_null = ::Thermostat::gamma_null;
177 auto const gamma = m_handle.get()->*member;
178 return (gamma >= gamma_null) ? Variant{gamma} : Variant{None{}};
179 }};
180 }
181
183 auto params = parameters;
184 if (not is_seed_required()) {
185 for (auto key : {std::string("seed"), std::string("philox_counter")}) {
186 if (not params.contains(key)) {
187 params[key] = get_parameter(key);
188 }
189 }
190 }
191 return params;
192 }
193
194 Variant do_call_method(std::string const &name,
195 VariantMap const &params) override {
196 if (name == "override_philox_counter") {
197 // only call this method if you know what you are doing
198 set_rng_counter(params.at("counter"));
199 return {};
200 }
201 return {};
202 }
203
204public:
207 {"seed",
208 [this](Variant const &v) {
209 check_lock();
210 context()->parallel_try_catch([&]() {
211 if (not is_none(v))
212 set_rng_seed(v);
213 });
214 },
215 [this]() {
216 return m_handle->is_seed_required() ? Variant{None{}}
218 }},
219 {"philox_counter",
220 [this](Variant const &v) {
221 check_lock();
222 context()->parallel_try_catch([&]() {
223 if (not is_none(v))
225 });
226 },
227 [this]() { return get_rng_counter(); }},
228 {"is_active", AutoParameter::read_only, [this]() { return is_active; }},
229 });
230 }
231
232 virtual std::optional<double> extract_kT(VariantMap const &params) const {
233 if (params.contains("kT")) {
234 auto const value = get_value<double>(params, "kT");
235 sanity_checks_positive(value, "kT");
236 return value;
237 }
238 return {std::nullopt};
239 }
240
242 auto lock = std::make_shared<bool>(false);
244 return lock;
245 }
246
247 auto is_activated() const { return is_active; }
248
249 virtual bool is_seed_required() const { return m_handle->is_seed_required(); }
250
251 auto get_rng_seed() const {
252 auto const seed = m_handle->rng_seed();
253 assert(seed <= static_cast<uint32_t>(std::numeric_limits<int>::max()));
254 return static_cast<int>(seed);
255 }
256
257 auto get_rng_counter() const {
258 auto const counter = m_handle->rng_counter();
259 assert(counter <= static_cast<uint64_t>(std::numeric_limits<int>::max()));
260 return static_cast<int>(counter);
261 }
262
263 void set_rng_seed(Variant const &value) {
264 auto const seed = get_value<int>(value);
265 if (seed < 0) {
266 throw std::domain_error("Parameter 'seed' must be a positive integer");
267 }
268 assert(static_cast<uint64_t>(seed) <=
269 static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()));
270 m_handle->rng_initialize(static_cast<uint32_t>(seed));
271 }
272
273 void set_rng_counter(Variant const &value) {
274 auto const counter = get_value<int>(value);
275 assert(counter >= 0);
276 assert(static_cast<uint64_t>(counter) <=
277 std::numeric_limits<uint64_t>::max());
278 m_handle->set_rng_counter(static_cast<uint64_t>(counter));
279 }
280
281 void do_construct(VariantMap const &params) override {
282 m_handle = std::make_shared<CoreThermostat>();
283 if (not params.empty()) {
284 auto const read_write_lock = release_lock();
285 set_new_parameters(params);
286 }
287 }
288
289 void update_and_bind(VariantMap const &params, bool was_active,
290 std::shared_ptr<::System::System> system) {
291 auto const old_handle = m_handle;
292 auto new_params = extend_parameters(params);
293 new_params["__global_kT"] = system->thermostat->kT;
294 new_params["__check_rng_state"] = true;
295 try {
296 m_handle = std::make_shared<CoreThermostat>();
297 set_new_parameters(new_params);
299 } catch (...) {
302 if (was_active) {
304 }
305 throw;
306 }
307 }
308
309 virtual ::ThermostatFlags get_thermo_flag() const = 0;
310};
311
312class Langevin : public Interface<::LangevinThermostat> {
313 std::shared_ptr<CoreThermostat> &
315 return thermostat.langevin;
316 }
317
318 std::span<std::string_view const> get_required_parameters() const override {
319 static constexpr std::array names{std::string_view("gamma")};
320 return names;
321 }
322
323public:
327#ifdef ESPRESSO_ROTATION
329#endif
330 });
331 }
332
334
335protected:
337 auto params =
339#ifdef ESPRESSO_ROTATION
340 // If gamma_rotation is not set explicitly, use the translational one.
341 if (not params.contains("gamma_rotation") and params.contains("gamma")) {
342 params["gamma_rotation"] = params.at("gamma");
343 }
344#endif // ESPRESSO_ROTATION
345 return params;
346 }
347};
348
349class Brownian : public Interface<::BrownianThermostat> {
350 std::shared_ptr<CoreThermostat> &
352 return thermostat.brownian;
353 }
354
355 std::span<std::string_view const> get_required_parameters() const override {
356 static constexpr std::array names{std::string_view("gamma")};
357 return names;
358 }
359
360public:
364#ifdef ESPRESSO_ROTATION
366#endif
367 });
368 }
369
371
372protected:
374 auto params =
376#ifdef ESPRESSO_ROTATION
377 // If gamma_rotation is not set explicitly, use the translational one.
378 if (not params.contains("gamma_rotation") and params.contains("gamma")) {
379 params["gamma_rotation"] = params.at("gamma");
380 }
381#endif // ESPRESSO_ROTATION
382 return params;
383 }
384};
385
386#ifdef ESPRESSO_NPT
387class IsotropicNpt : public Interface<::IsotropicNptThermostat> {
388 std::shared_ptr<CoreThermostat> &
390 return thermostat.npt_iso;
391 }
392
393 std::span<std::string_view const> get_required_parameters() const override {
394 static constexpr std::array names{std::string_view("gamma0"),
395 std::string_view("gammav")};
396 return names;
397 }
398
399public:
406
408};
409#endif // ESPRESSO_NPT
410
411#ifdef ESPRESSO_WALBERLA
412class LBThermostat : public Interface<::LBThermostat> {
413 std::shared_ptr<CoreThermostat> &
415 return thermostat.lb;
416 }
417
418public:
421 {"gamma",
422 [this](Variant const &v) {
423 check_lock();
424 if (is_none(v)) {
425 return;
426 }
427 auto const gamma = get_value<double>(v);
429 [&]() { sanity_checks_positive(gamma, "gamma"); });
430 m_handle->gamma = gamma;
431 },
432 [this]() {
433 auto const gamma = m_handle->gamma;
434 return (gamma >= 0.) ? Variant{gamma} : Variant{None{}};
435 }},
436 });
437 }
438
440
441 std::optional<double> extract_kT(VariantMap const &params) const override {
442 auto const obj =
444 auto const value = get_value<double>(obj->get_parameter("kT"));
445 sanity_checks_positive(value, "kT");
446 return value;
447 }
448
449protected:
450 bool invalid_rng_state(VariantMap const &params) const override {
451 return (not params.contains("seed") or is_none(params.at("seed"))) and
452 params.contains("__global_kT") and is_seed_required() and
453 get_value<double>(params, "__global_kT") != 0.;
454 }
455
456 std::span<std::string_view const> get_required_parameters() const override {
457 static constexpr std::array names{std::string_view("gamma")};
458 return names;
459 }
460};
461#endif // ESPRESSO_WALBERLA
462
463#ifdef ESPRESSO_DPD
464class DPDThermostat : public Interface<::DPDThermostat> {
465 std::shared_ptr<CoreThermostat> &
467 return thermostat.dpd;
468 }
469
470 std::span<std::string_view const> get_required_parameters() const override {
471 return {};
472 }
473
474public:
476};
477#endif
478
479#ifdef ESPRESSO_STOKESIAN_DYNAMICS
480class Stokesian : public Interface<::StokesianThermostat> {
481 std::shared_ptr<CoreThermostat> &
483 return thermostat.stokesian;
484 }
485
486 std::span<std::string_view const> get_required_parameters() const override {
487 return {};
488 }
489
490public:
492};
493#endif
494
495class ThermalizedBond : public Interface<::ThermalizedBondThermostat> {
496 std::shared_ptr<CoreThermostat> &
498 return thermostat.thermalized_bond;
499 }
500
501 std::span<std::string_view const> get_required_parameters() const override {
502 return {};
503 }
504
505public:
507};
508
509class Thermostat : public AutoParameters<Thermostat, System::Leaf> {
510 std::shared_ptr<Langevin> langevin;
511 std::shared_ptr<Brownian> brownian;
512#ifdef ESPRESSO_NPT
513 std::shared_ptr<IsotropicNpt> npt_iso;
514#endif
515#ifdef ESPRESSO_WALBERLA
516 std::shared_ptr<LBThermostat> lb;
517#endif
518#ifdef ESPRESSO_DPD
519 std::shared_ptr<DPDThermostat> dpd;
520#endif
521#ifdef ESPRESSO_STOKESIAN_DYNAMICS
522 std::shared_ptr<Stokesian> stokesian;
523#endif
524 std::shared_ptr<ThermalizedBond> thermalized_bond;
525 std::shared_ptr<::Thermostat::Thermostat> m_handle;
526 std::unique_ptr<VariantMap> m_params;
527
528 template <typename Fun> void apply(Fun fun) {
529 fun(*langevin);
530 fun(*brownian);
531#ifdef ESPRESSO_NPT
532 fun(*npt_iso);
533#endif
534#ifdef ESPRESSO_WALBERLA
535 fun(*lb);
536#endif
537#ifdef ESPRESSO_DPD
538 fun(*dpd);
539#endif
540#ifdef ESPRESSO_STOKESIAN_DYNAMICS
541 fun(*stokesian);
542#endif
543 fun(*thermalized_bond);
544 }
545
546protected:
547 template <typename T>
549 return AutoParameter{
550 name,
551 [this, member, name = std::string(name)](Variant const &v) {
552 auto &thermostat = this->*member;
553 if (thermostat) {
554 throw WriteError{name};
555 }
556 thermostat = get_value<T>(v);
557 },
558 [this, member]() { return this->*member; }};
559 }
560
561 template <typename T>
562 void setup_thermostat(std::shared_ptr<T> &thermostat,
563 VariantMap const &params) {
564 auto const original_kT = m_handle->kT;
565 std::optional<double> new_kT;
567 [&]() { new_kT = thermostat->extract_kT(params); });
568 auto const thermo_flag = thermostat->get_thermo_flag();
569 if (new_kT) {
572 }
573 auto const was_active = thermostat->is_activated();
574 turn_thermostat_off(*thermostat);
575 auto read_write_lock = thermostat->release_lock();
576 context()->parallel_try_catch([&]() {
577 try {
578 if (new_kT) {
579 m_handle->kT = *new_kT;
580 }
581 thermostat->update_and_bind(params, was_active, m_system.lock());
582 m_handle->thermo_switch |= thermo_flag;
583 } catch (...) {
584 auto success = false;
585 try {
586 m_handle->kT = original_kT;
587 if (was_active) {
588 m_handle->thermo_switch |= thermo_flag;
589 thermostat->bind_system(m_system.lock());
590 }
591 success = true;
592 throw success;
593 } catch (...) {
594 assert(success &&
595 "An exception occurred when setting up the thermostat. "
596 "An exception also occurred when attempting to restore the "
597 "original thermostat. The system is now in an invalid state.");
598 }
599 throw;
600 }
601 });
602 }
603
604 template <typename T> void turn_thermostat_off(T &thermostat) {
605 auto const thermo_flag = thermostat.get_thermo_flag();
606 if (m_handle->thermo_switch & thermo_flag) {
607 thermostat.detach_system();
608 m_handle->thermo_switch &= ~thermo_flag;
609 if (m_handle->thermo_switch == 0) {
610 m_handle->kT = -1.;
611 }
612 }
613 }
614
615 void update_global_kT(double old_kT, double new_kT, int thermo_flag) {
616 if (new_kT >= 0.) {
618 auto const thermo_switch = m_handle->thermo_switch;
619 if (thermo_switch != THERMO_OFF and thermo_switch != thermo_flag and
620 thermo_switch != THERMO_BOND and not same_kT and old_kT >= 0.) {
621 throw std::runtime_error(
622 "Cannot set parameter 'kT' to " + std::to_string(new_kT) +
623 ": there are currently active thermostats with kT=" +
624 std::to_string(old_kT));
625 }
626 get_system().check_kT(new_kT);
627 if (not same_kT) {
628 m_handle->kT = new_kT;
629 get_system().on_temperature_change();
630 }
631 }
632 }
633
634public:
638 [this]() {
639 return (m_handle->kT >= 0.) ? Variant{m_handle->kT}
640 : Variant{None{}};
641 }},
642 make_autoparameter(&Thermostat::langevin, "langevin"),
643 make_autoparameter(&Thermostat::brownian, "brownian"),
644#ifdef ESPRESSO_NPT
645 make_autoparameter(&Thermostat::npt_iso, "npt_iso"),
646#endif
647#ifdef ESPRESSO_WALBERLA
648 make_autoparameter(&Thermostat::lb, "lb"),
649#endif
650#ifdef ESPRESSO_DPD
651 make_autoparameter(&Thermostat::dpd, "dpd"),
652#endif
653#ifdef ESPRESSO_STOKESIAN_DYNAMICS
654 make_autoparameter(&Thermostat::stokesian, "stokesian"),
655#endif
656 make_autoparameter(&Thermostat::thermalized_bond, "thermalized_bond"),
657 });
658 }
659
660 Variant do_call_method(std::string const &name,
661 VariantMap const &params) override {
662 if (params.contains("act_on_virtual")) {
663 context()->parallel_try_catch([&]() {
664 throw std::runtime_error(
665 name + "() got an unexpected keyword argument 'act_on_virtual'");
666 });
667 }
668 if (name == "set_langevin") {
669 setup_thermostat(langevin, params);
670 return {};
671 }
672 if (name == "set_brownian") {
673 setup_thermostat(brownian, params);
674 return {};
675 }
676#ifdef ESPRESSO_NPT
677 if (name == "set_npt") {
678 setup_thermostat(npt_iso, params);
679 return {};
680 }
681#endif // ESPRESSO_NPT
682#ifdef ESPRESSO_WALBERLA
683 if (name == "set_lb") {
684 setup_thermostat(lb, params);
685 return {};
686 }
687#endif // ESPRESSO_WALBERLA
688#ifdef ESPRESSO_DPD
689 if (name == "set_dpd") {
690 setup_thermostat(dpd, params);
691 return {};
692 }
693#endif // ESPRESSO_DPD
694#ifdef ESPRESSO_STOKESIAN_DYNAMICS
695 if (name == "set_stokesian") {
696 setup_thermostat(stokesian, params);
697 return {};
698 }
699#endif // ESPRESSO_STOKESIAN_DYNAMICS
700 if (name == "set_thermalized_bond") {
701 setup_thermostat(thermalized_bond, params);
702 return {};
703 }
704 if (name == "turn_off") {
705 apply([this](auto &thermostat) { turn_thermostat_off(thermostat); });
706 assert(m_handle->thermo_switch == THERMO_OFF);
707 get_system().on_temperature_change();
708 return {};
709 }
710 if (context()->is_head_node()) {
711 throw std::runtime_error(
712 "Unknown method " + name +
713 "(). Hint: a feature is probably not compiled in.");
714 }
715 return {};
716 }
717
718 void do_construct(VariantMap const &params) override {
719 m_params = std::make_unique<VariantMap>(params);
720 }
721
723 assert(m_params != nullptr);
724 m_handle = system.thermostat;
725 auto const &params = *m_params;
726 if (not params.empty()) {
727 reload_checkpointed_thermostats(params);
728 m_params.reset();
729 return;
730 }
731 m_params.reset();
732 if (not context()->is_head_node()) {
733 return;
734 }
735 make_default_constructed_thermostats();
736 }
737
738private:
739 /**
740 * @brief Reload thermostats from checkpointed data.
741 */
742 void reload_checkpointed_thermostats(VariantMap const &params) {
743 for (auto const &key : get_parameter_insertion_order()) {
744 if (key != "kT") {
745 auto const &v = params.at(key);
746 do_set_parameter(key.c_str(), v);
747 }
748 }
749 if (not is_none(params.at("kT"))) {
750 m_handle->kT = get_value<double>(params, "kT");
751 }
752 apply([this](auto &thermostat) {
753 if (get_value<bool>(thermostat.get_parameter("is_active"))) {
754 thermostat.bind_system(m_system.lock());
755 m_handle->thermo_switch |= thermostat.get_thermo_flag();
756 }
757 });
758 get_system().on_thermostat_param_change();
759 }
760
761 /**
762 * @brief Instantiate default-constructed thermostats.
763 * Can only be run on the head node!
764 */
765 void make_default_constructed_thermostats() {
766 assert(context()->is_head_node());
767 auto const make_thermostat = [this](char const *name, char const *so_name) {
769 };
770 make_thermostat("langevin", "Thermostat::Langevin");
771 make_thermostat("brownian", "Thermostat::Brownian");
772#ifdef ESPRESSO_NPT
773 make_thermostat("npt_iso", "Thermostat::IsotropicNpt");
774#endif
775#ifdef ESPRESSO_WALBERLA
776 make_thermostat("lb", "Thermostat::LB");
777#endif
778#ifdef ESPRESSO_DPD
779 make_thermostat("dpd", "Thermostat::DPD");
780#endif
781#ifdef ESPRESSO_STOKESIAN_DYNAMICS
782 make_thermostat("stokesian", "Thermostat::Stokesian");
783#endif
784 make_thermostat("thermalized_bond", "Thermostat::ThermalizedBond");
785 }
786};
787
788} // namespace Thermostat
789} // namespace ScriptInterface
ScriptInterface::Context decorates ScriptInterface::ObjectHandle objects with a context: a creation p...
ThermostatFlags
Thermostat flags.
@ THERMO_SD
@ THERMO_BROWNIAN
@ THERMO_BOND
@ THERMO_LB
@ THERMO_LANGEVIN
@ THERMO_DPD
@ THERMO_NPT_ISO
@ THERMO_OFF
Data structures for bonded interactions.
Bind parameters in the script interface.
void do_set_parameter(const std::string &name, const Variant &value) final
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
virtual std::shared_ptr< ObjectHandle > make_shared(std::string const &name, const VariantMap &parameters)=0
Get a new reference counted instance of a script interface by name.
Type to indicate no value in Variant.
Definition None.hpp:31
Context * context() const
Responsible context.
void set_parameter(const std::string &name, const Variant &value)
Set single parameter.
std::string_view name() const
Script interface wrapper for a component of the system class.
std::weak_ptr<::System::System > m_system
void bind_system(std::shared_ptr<::System::System > const &system)
VariantMap extend_parameters(VariantMap const &parameters) const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
std::span< std::string_view const > get_required_parameters() const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
std::span< std::string_view const > get_required_parameters() const override
void sanity_checks_positive(double value, std::string const &name) const
void update_and_bind(VariantMap const &params, bool was_active, std::shared_ptr<::System::System > system)
virtual ::ThermostatFlags get_thermo_flag() const =0
virtual std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat)=0
virtual bool invalid_rng_state(VariantMap const &params) const
auto make_autoparameter(T CoreThermostat::*member, char const *name)
Variant do_call_method(std::string const &name, VariantMap const &params) override
virtual std::span< std::string_view const > get_required_parameters() const =0
virtual std::optional< double > extract_kT(VariantMap const &params) const
auto make_autogamma(T CoreThermostat::*member, char const *name)
virtual VariantMap extend_parameters(VariantMap const &parameters) const
std::weak_ptr< bool > m_edit_lock
Basic lock mechanism that follows RAII.
void sanity_checks_positive(Utils::Vector3d const &value, std::string const &name) const
std::span< std::string_view const > get_required_parameters() const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
bool invalid_rng_state(VariantMap const &params) const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
std::optional< double > extract_kT(VariantMap const &params) const override
std::span< std::string_view const > get_required_parameters() const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
std::span< std::string_view const > get_required_parameters() const override
VariantMap extend_parameters(VariantMap const &parameters) const override
std::span< std::string_view const > get_required_parameters() const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
std::span< std::string_view const > get_required_parameters() const override
std::shared_ptr< CoreThermostat > & get_member_handle(::Thermostat::Thermostat &thermostat) override
void update_global_kT(double old_kT, double new_kT, int thermo_flag)
auto make_autoparameter(T Thermostat::*member, char const *name)
void setup_thermostat(std::shared_ptr< T > &thermostat, VariantMap const &params)
Variant do_call_method(std::string const &name, VariantMap const &params) override
Main system class.
std::shared_ptr< BrownianThermostat > brownian
std::shared_ptr< ThermalizedBondThermostat > thermalized_bond
std::shared_ptr< LangevinThermostat > langevin
std::shared_ptr< DPDThermostat > dpd
std::shared_ptr< LBThermostat > lb
std::shared_ptr< IsotropicNptThermostat > npt_iso
std::shared_ptr< StokesianThermostat > stokesian
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
Definition Vector.hpp:138
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
Implementation in thermostat.cpp.
constexpr bool is_none(Variant const &v)
Definition Variant.hpp:163
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:133
make_recursive_variant< ObjectRef > Variant
Possible types for parameters.
Definition Variant.hpp:131
bool are_kT_equal(double old_kT, double new_kT)
Check that two kT values are close up to a small tolerance.
constexpr GammaType gamma_null
Value for a null friction coefficient.
GammaType gamma
Translational friction coefficient .
GammaType gamma_rotation
Rotational friction coefficient .
double gamma0
Friction coefficient of the particles .
double gammav
Friction coefficient for the box .
GammaType gamma_rotation
Rotational friction coefficient .
GammaType gamma
Translational friction coefficient .
Description and getter/setter for a parameter.
static constexpr const ReadOnly read_only
Recursive variant implementation.
Definition Variant.hpp:84