ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
ParticleSlice.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022-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
22#include "ParticleHandle.hpp"
23
30
32
34
35#include <algorithm>
36#include <cassert>
37#include <functional>
38#include <memory>
39#include <ranges>
40#include <string>
41#include <string_view>
42#include <type_traits>
43#include <unordered_map>
44#include <utility>
45#include <vector>
46
47namespace ScriptInterface {
48namespace Particles {
49namespace traits {
50template <typename T> struct is_vector_like : std::false_type {};
51template <typename T, typename Alloc>
52struct is_vector_like<std::vector<T, Alloc>> : std::true_type {};
53template <typename T, std::size_t N>
54struct is_vector_like<Utils::Vector<T, N>> : std::true_type {};
55} // namespace traits
56
57template <class Container>
59 std::vector<int> const &pids, std::string const &param_name,
60 Container const &values, Context *context,
61 std::shared_ptr<CellSystem::CellSystem> cell_structure,
62 std::shared_ptr<Interactions::BondedInteractions> bonded_ias) {
63
65 VariantMap const obj_params{{"id", -1},
66 {"__cell_structure", cell_structure},
67 {"__bonded_ias", bonded_ias}};
68 auto so = std::dynamic_pointer_cast<ParticleModifier>(
69 context->make_shared("Particles::ParticleModifier", obj_params));
70 for (std::size_t i = 0; i < pids.size(); ++i) {
71 so->set_pid(pids[i]);
72 so->do_set_parameter(param_name, values[i]);
73 }
74 } else {
75 throw Exception("Values must be of type vector, got " +
76 detail::demangle::simplify_symbol(&values));
77 }
78}
79
80template <typename T>
81inline auto
82get_particles_properties(std::vector<int> const &pids,
83 std::function<T(Particle const &)> const &getter,
84 Context *context,
85 CellStructure const &cell_structure) {
86
87 using value_type =
88 std::conditional_t<Variant::has_type<std::vector<T>>::value, T, Variant>;
89 std::vector<value_type> result;
90
91 auto const n_ranks = static_cast<std::size_t>(context->get_comm().size());
92 auto const size_hint = pids.size() / n_ranks;
93 std::vector<std::pair<int, T>> parameters;
94 parameters.reserve(size_hint);
95 for (auto const &pid : pids) {
96 auto const p = cell_structure.get_local_particle(pid);
97 if (p and not p->is_ghost()) {
98 parameters.emplace_back(pid, getter(*p));
99 }
100 }
101
102 // collect values from all nodes
104 if (!context->is_head_node()) {
105 return result;
106 }
107
108 // reorder gathered values to match the caller's id_selection order
109 assert(parameters.size() == pids.size() &&
110 "Missing or duplicate particle ids");
111 std::unordered_map<int, std::size_t> lookup;
112 lookup.reserve(parameters.size());
113 std::size_t p_index = 0u;
114 for (auto const pid : pids) {
115 lookup[pid] = p_index;
116 ++p_index;
117 }
118 result.resize(pids.size());
119 for (auto &[pid, val] : parameters) {
120 result[lookup[pid]] = std::move(val);
121 }
122 return result;
123}
124
125class ParticleSlice : public AutoParameters<ParticleSlice> {
126 std::vector<int> m_id_selection;
127 int m_chunk_size;
128 std::weak_ptr<CellSystem::CellSystem> m_cell_structure;
129 std::weak_ptr<Interactions::BondedInteractions> m_bonded_ias;
130 std::weak_ptr<::System::System> m_system;
131 /** @brief Data structure to store names of parameters with special setters.
132 */
133 std::set<std::string_view> const m_special_parameters{
134 "pos", "type", "bonds",
135#ifdef ESPRESSO_ELECTROSTATICS
136 "q",
137#endif // ESPRESSO_ELECTROSTATICS
138#ifdef ESPRESSO_EXCLUSIONS
139 "exclusions",
140#endif // ESPRESSO_EXCLUSIONS
141 };
142
143 auto get_cell_structure() const {
144 auto cell_structure_ptr = m_cell_structure.lock();
145 assert(cell_structure_ptr != nullptr);
146 auto &cell_structure = cell_structure_ptr->get_cell_structure();
147 return &cell_structure;
148 }
149
150 auto get_system() const {
151 auto ptr = m_system.lock();
152 assert(ptr != nullptr);
153 return ptr;
154 }
155
156public:
159 {"chunk_size", AutoParameter::read_only,
160 [this]() { return m_chunk_size; }},
161 {"id_selection", AutoParameter::read_only,
162 [this]() { return m_id_selection; }},
163 });
164 }
165
166 void do_construct(VariantMap const &params) override;
167
168 Variant do_call_method(std::string const &name,
169 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} // namespace Particles
178} // 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.
void add_parameters(std::vector< AutoParameter > &&params)
Context of an object handle.
Definition Context.hpp:53
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.
virtual bool is_head_node() const =0
virtual boost::mpi::communicator const & get_comm() const =0
std::string_view name() const
void attach(std::weak_ptr<::System::System > system)
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 set_from_vector_like(std::vector< int > const &pids, std::string const &param_name, Container const &values, Context *context, std::shared_ptr< CellSystem::CellSystem > cell_structure, std::shared_ptr< Interactions::BondedInteractions > bonded_ias)
auto get_particles_properties(std::vector< int > const &pids, std::function< T(Particle const &)> const &getter, Context *context, CellStructure const &cell_structure)
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:133
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
STL namespace.
Struct holding all information for one particle.
Definition Particle.hpp:436
static constexpr const ReadOnly read_only
Recursive variant implementation.
Definition Variant.hpp:84