ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
ParticleHandle.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 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
25
26#include "core/Particle.hpp"
27#include "core/exclusions.hpp"
29
30#include <boost/mpi/collectives/all_reduce.hpp>
31
32#include <cassert>
33#include <cstddef>
34#include <functional>
35#include <memory>
36#include <stdexcept>
37#include <string>
38
39namespace ScriptInterface {
40namespace CellSystem {
41class CellSystem;
42}
43namespace Particles {
44
45class ParticleModifier;
46
47inline auto error_msg(std::string const &name, std::string const &reason) {
48 std::stringstream msg;
49 msg << "attribute '" << name << "' of 'ParticleHandle' " << reason;
50 return msg.str();
51}
52
53inline auto get_real_particle(boost::mpi::communicator const &comm, int p_id,
54 ::CellStructure &cell_structure) {
55 if (p_id < 0) {
56 throw std::domain_error("Invalid particle id: " + std::to_string(p_id));
57 }
58 auto ptr = cell_structure.get_local_particle(p_id);
59 if (ptr != nullptr and ptr->is_ghost()) {
60 ptr = nullptr;
61 }
62 auto const n_found = boost::mpi::all_reduce(
63 comm, static_cast<int>(ptr != nullptr), std::plus<>());
64 if (n_found == 0) {
65 throw std::runtime_error("Particle with id " + std::to_string(p_id) +
66 " not found");
67 }
68 return ptr;
69}
70
71inline void particle_checks(int p_id, Utils::Vector3d const &pos) {
72 if (p_id < 0) {
73 throw std::domain_error("Invalid particle id: " + std::to_string(p_id));
74 }
75#ifndef __FAST_MATH__
76 if (std::isnan(pos[0]) or std::isnan(pos[1]) or std::isnan(pos[2]) or
77 std::isinf(pos[0]) or std::isinf(pos[1]) or std::isinf(pos[2])) {
78 throw std::domain_error("Particle position must be finite");
79 }
80#endif // __FAST_MATH__
81}
82
83#ifdef ESPRESSO_EXCLUSIONS
84/**
85 * @brief Locally add an exclusion to a particle.
86 * @param pid1 the identity of the first exclusion partner
87 * @param pid2 the identity of the second exclusion partner
88 * @param cell_structure the cell structure
89 */
90inline void local_add_exclusion(int pid1, int pid2,
91 ::CellStructure &cell_structure) {
92 if (auto p1 = cell_structure.get_local_particle(pid1)) {
94 }
95 if (auto p2 = cell_structure.get_local_particle(pid2)) {
97 }
98}
99
100/**
101 * @brief Locally remove an exclusion to a particle.
102 * @param pid1 the identity of the first exclusion partner
103 * @param pid2 the identity of the second exclusion partner
104 * @param cell_structure the cell structure
105 */
106inline void local_remove_exclusion(int pid1, int pid2,
107 ::CellStructure &cell_structure) {
108 if (auto p1 = cell_structure.get_local_particle(pid1)) {
110 }
111 if (auto p2 = cell_structure.get_local_particle(pid2)) {
113 }
114}
115
117 ::CellStructure &cell_structure,
118 auto const &comm) {
119 if (pid1 == pid2) {
120 throw std::runtime_error("Particles cannot exclude themselves (id " +
121 std::to_string(pid1) + ")");
122 }
123 std::ignore = get_real_particle(comm, pid1, cell_structure);
124 std::ignore = get_real_particle(comm, pid2, cell_structure);
125}
126#endif // ESPRESSO_EXCLUSIONS
127
128class ParticleHandle : public AutoParameters<ParticleHandle> {
129 std::function<Variant(VariantMap const &)> cb_get_bond;
130 int m_pid;
131 mutable std::weak_ptr<CellSystem::CellSystem> m_cell_structure;
132 mutable std::weak_ptr<Interactions::BondedInteractions> m_bonded_ias;
133 mutable std::weak_ptr<::System::System> m_system;
134 auto get_cell_structure() const {
135 auto ptr = m_cell_structure.lock();
136 assert(ptr != nullptr);
137 return ptr;
138 }
139 auto get_bonded_ias() const {
140 auto ptr = m_bonded_ias.lock();
141 assert(ptr != nullptr);
142 return ptr;
143 }
144 auto get_system() const {
145 auto ptr = m_system.lock();
146 assert(ptr != nullptr);
147 return ptr;
148 }
149
150 template <typename T>
151 T get_particle_property(T const &(Particle::*getter)() const) const;
152 template <typename T, class F> T get_particle_property(F const &fun) const;
153
154 template <typename T>
155 void set_particle_property(T &(Particle::*setter)(),
156 Variant const &value) const;
157
158 template <class F> void set_particle_property(F const &fun) const;
159
160 std::size_t setup_hidden_args(VariantMap const &params);
161
162public:
164 friend class ParticleModifier;
165
166 Variant do_call_method(std::string const &name,
167 VariantMap const &params) override;
168
169 void do_construct(VariantMap const &params) override;
170
171 void attach(std::weak_ptr<::System::System> system) {
172 assert(m_system.expired());
173 m_system = system;
174 }
175};
176
177/** @brief Thin wrapper to read and write particle attributes in batches. */
179public:
180 void do_construct(VariantMap const &params) override {
181 auto const n_extra_args = setup_hidden_args(params);
182 if (n_extra_args) {
183 throw std::logic_error(
184 "ParticleModifier is not meant to create new particles");
185 }
186 m_pid = params.contains("id") ? get_value<int>(params, "id") : -1;
187 }
188
189 void set_pid(int pid) {
190 assert(pid >= 0);
191 m_pid = pid;
192 }
193
194 Variant do_call_method(std::string const &name,
195 VariantMap const &params) override {
196 if (name == "remove_particle") {
197 throw std::logic_error("ParticleModifier has no method '" + name + "'");
198 }
200 }
201};
202
203} // namespace Particles
204} // namespace ScriptInterface
Describes a cell structure / cell system.
Particle * get_local_particle(int id)
Get a local particle by id.
Bind parameters in the script interface.
std::string_view name() const
Variant do_call_method(std::string const &name, VariantMap const &params) override
void attach(std::weak_ptr<::System::System > system)
void do_construct(VariantMap const &params) override
Thin wrapper to read and write particle attributes in batches.
Variant do_call_method(std::string const &name, VariantMap const &params) override
void do_construct(VariantMap const &params) override
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
void delete_exclusion(Particle &p, int p_id)
Remove exclusion from particle if possible.
void add_exclusion(Particle &p, int p_id)
Insert an exclusion if not already set.
auto get_real_particle(boost::mpi::communicator const &comm, int p_id, ::CellStructure &cell_structure)
void particle_exclusion_sanity_checks(int pid1, int pid2, ::CellStructure &cell_structure, auto const &comm)
void local_remove_exclusion(int pid1, int pid2, ::CellStructure &cell_structure)
Locally remove an exclusion to a particle.
void particle_checks(int p_id, Utils::Vector3d const &pos)
auto error_msg(std::string const &name, std::string const &reason)
void local_add_exclusion(int pid1, int pid2, ::CellStructure &cell_structure)
Locally add an exclusion to a particle.
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:133
make_recursive_variant< ObjectRef > Variant
Possible types for parameters.
Definition Variant.hpp:131
static SteepestDescentParameters params
Currently active steepest descent instance.
Struct holding all information for one particle.
Definition Particle.hpp:450
Recursive variant implementation.
Definition Variant.hpp:84