67std::string ParticleList::get_internal_state()
const {
69 std::vector<std::string> object_states(p_ids.size());
71 boost::transform(p_ids, object_states.begin(), [
this](
auto const p_id) {
73 context()->make_shared(
"Particles::ParticleHandle", {{
"id", p_id}});
75 auto const packed_state = p_handle.
serialize();
77 auto state = Utils::unpack<ObjectState>(packed_state);
78 state.name =
"Particles::ParticleHandle";
79 auto const bonds_view = p_handle.call_method(
"get_bonds_view", {});
80 state.params.emplace_back(std::string{
"bonds"},
pack(bonds_view));
82 auto const exclusions = p_handle.call_method(
"get_exclusions", {});
83 state.params.emplace_back(std::string{
"exclusions"},
pack(exclusions));
85 state.params.emplace_back(std::string{
"__cpt_sentinel"},
pack(
None{}));
92void ParticleList::set_internal_state(std::string
const &state) {
93 auto const object_states = Utils::unpack<std::vector<std::string>>(state);
95 std::unordered_map<int, Variant> exclusions = {};
97 std::unordered_map<int, Variant> bonds = {};
99 for (
auto const &packed_object : object_states) {
100 auto state = Utils::unpack<ObjectState>(packed_object);
102 for (
auto const &kv : state.params) {
105 auto const p_id = get_value<int>(
params.at(
"id"));
106 bonds[p_id] =
params.extract(
"bonds").mapped();
108 exclusions[p_id] =
params.extract(
"exclusions").mapped();
110 context()->make_shared(
"Particles::ParticleHandle",
params);
115 context()->make_shared(
"Particles::ParticleHandle", {{
"id", p_id}});
130 int const n_bonds_max) {
132 std::unordered_map<int, std::vector<std::pair<int, int>>> partners;
133 std::vector<int> bonded_pairs;
136 auto &cell_structure = *system.cell_structure;
139 for (
auto const &p : cell_structure.local_particles()) {
140 auto const pid1 = p.id();
141 for (
auto const bond : p.bonds()) {
142 if (bond.partner_ids().size() == 1) {
143 auto const pid2 = bond.partner_ids()[0];
145 bonded_pairs.emplace_back(pid1);
146 bonded_pairs.emplace_back(pid2);
154 if (comm.rank() == 0) {
155 auto const add_partner = [&partners](
int pid1,
int pid2,
int n_bonds) {
158 for (
auto const &partner : partners[pid1])
159 if (partner.first == pid2)
161 partners[pid1].emplace_back(pid2, n_bonds);
164 for (
auto it = bonded_pairs.begin(); it != bonded_pairs.end(); it += 2) {
165 add_partner(it[0], it[1], 1);
166 add_partner(it[1], it[0], 1);
170 for (
int iteration = 1; iteration < n_bonds_max; iteration++) {
171 std::vector<int> pids;
172 for (
auto const &kv : partners) {
173 pids.emplace_back(kv.first);
175 for (
auto const pid1 : pids) {
178 for (std::size_t i = 0
u; i < partners[pid1].size(); ++i) {
179 auto const [pid2, dist21] = partners[pid1][i];
180 if (dist21 > n_bonds_max)
184 for (std::size_t j = 0
u; j < partners[pid2].size(); ++j) {
185 auto const [pid3, dist32] = partners[pid2][j];
186 auto const dist31 = dist32 + dist21;
187 if (dist31 > n_bonds_max)
189 add_partner(pid1, pid3, dist31);
190 add_partner(pid3, pid1, dist31);
197 boost::mpi::broadcast(comm, partners, 0);
198 for (
auto const &kv : partners) {
199 auto const pid1 = kv.first;
200 auto const &partner_list = kv.second;
201 for (
auto const &partner : partner_list) {
202 auto const pid2 = partner.first;
203 if (
auto p1 = cell_structure.get_local_particle(pid1)) {
206 if (
auto p2 = cell_structure.get_local_particle(pid2)) {
211 system.on_particle_change();
static void set_bonds(ParticleHandle &p, Variant const &bonds)
static void set_exclusions(ParticleHandle &p, Variant const &exclusions)
static void auto_exclusions(boost::mpi::communicator const &comm, int const n_bonds_max)
Use the bond topology to automatically add exclusions between particles that are up to n_bonds_max bo...
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.
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
void remove_all_particles()
Remove all particles.
int get_maximal_particle_id()
Get maximal particle id.
std::vector< int > get_particle_ids()
Get all particle ids.
bool particle_exists(int p_id)
Check if particle exists.
Particles creation and deletion.