ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
cells.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2026 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21/** \file
22 *
23 * This file contains functions for the cell system.
24 *
25 * Implementation of cells.hpp.
26 */
27
28#include "cells.hpp"
29
30#include "cell_system/Cell.hpp"
34
35#include "Particle.hpp"
36#include "communication.hpp"
37#include "errorhandling.hpp"
38#include "system/System.hpp"
39
40#include <utils/Vector.hpp>
41#include <utils/math/sqr.hpp>
42
43#include <boost/serialization/set.hpp>
44
45#include <algorithm>
46#include <optional>
47#include <stdexcept>
48#include <utility>
49#include <vector>
50
51/**
52 * @brief Get pairs of particles that are closer than a distance and fulfill a
53 * filter criterion.
54 *
55 * It uses link_cell to get pairs out of the cellsystem
56 * by a simple distance criterion and applies the filter on both particles.
57 *
58 * Pairs are sorted so that first.id < second.id
59 */
60template <class Filter>
61static auto get_pairs_filtered(System::System const &system,
62 double const distance, Filter filter) {
63 std::vector<std::pair<int, int>> ret;
64 auto const cutoff2 = Utils::sqr(distance);
65 auto const pair_kernel = [cutoff2, &filter, &ret](Particle const &p1,
66 Particle const &p2,
67 Distance const &d) {
68 if (d.dist2 < cutoff2 and filter(p1) and filter(p2)) {
69 auto pid1 = p1.id();
70 auto pid2 = p2.id();
71 if (pid1 > pid2) {
72 std::swap(pid1, pid2);
73 }
74 ret.emplace_back(pid1, pid2);
75 }
76 };
77
78 system.cell_structure->non_bonded_loop(pair_kernel);
79
80 return ret;
81}
82
83namespace detail {
84static auto get_max_neighbor_search_range(System::System const &system) {
85 auto const &cell_structure = *system.cell_structure;
86 return std::ranges::min(cell_structure.max_range());
87}
88static void search_distance_sanity_check_max_range(System::System const &system,
89 double const distance) {
90 /* get_pairs_filtered() finds pairs via the non_bonded_loop. The maximum
91 * finding range is therefore limited by the decomposition that is used.
92 */
93 auto const max_range = get_max_neighbor_search_range(system);
94 if (distance > max_range) {
95 throw std::domain_error("pair search distance " + std::to_string(distance) +
96 " bigger than the decomposition range " +
97 std::to_string(max_range));
98 }
99}
100static void
101search_distance_sanity_check_cell_structure(System::System const &system,
102 double const) {
103 auto const &cell_structure = *system.cell_structure;
104 if (cell_structure.decomposition_type() == CellStructureType::HYBRID) {
105 throw std::runtime_error("Cannot search for neighbors in the hybrid "
106 "decomposition cell system");
107 }
108}
109static void search_neighbors_sanity_checks(System::System const &system,
110 double const distance) {
111 search_distance_sanity_check_max_range(system, distance);
112 search_distance_sanity_check_cell_structure(system, distance);
113}
114} // namespace detail
115
116std::optional<std::vector<int>>
117get_short_range_neighbors(System::System const &system, int const pid,
118 double const distance) {
119 detail::search_neighbors_sanity_checks(system, distance);
120 std::vector<int> ret;
121 auto const cutoff2 = Utils::sqr(distance);
122 auto const kernel = [cutoff2, &ret](Particle const &, Particle const &p2,
123 Utils::Vector3d const &vec) {
124 if (vec.norm2() < cutoff2) {
125 ret.emplace_back(p2.id());
126 }
127 };
128 auto &cell_structure = *system.cell_structure;
129 auto const p = cell_structure.get_local_particle(pid);
130 if (p and not p->is_ghost()) {
131 cell_structure.run_on_particle_short_range_neighbors(*p, kernel);
132 return {ret};
133 }
134 return {};
135}
136
137/**
138 * @brief Get pointers to all interacting neighbors of a central particle.
139 */
141 Particle const &p) {
142 auto &cell_structure = *system.cell_structure;
143 auto const distance = std::ranges::min(cell_structure.max_range());
144 detail::search_neighbors_sanity_checks(system, distance);
145 std::vector<Particle const *> ret;
146 auto const cutoff2 = Utils::sqr(distance);
147 auto const kernel = [cutoff2, &ret](Particle const &, Particle const &p2,
148 Utils::Vector3d const &vec) {
149 if (vec.norm2() < cutoff2) {
150 ret.emplace_back(&p2);
151 }
152 };
153 cell_structure.run_on_particle_short_range_neighbors(p, kernel);
154 return ret;
155}
156
157std::vector<std::pair<int, int>> get_pairs(System::System const &system,
158 double const distance) {
159 detail::search_neighbors_sanity_checks(system, distance);
160 return get_pairs_filtered(system, distance,
161 [](Particle const &) { return true; });
162}
163
164std::vector<std::pair<int, int>>
165get_pairs_of_types(System::System const &system, double const distance,
166 std::vector<int> const &types) {
167 detail::search_neighbors_sanity_checks(system, distance);
168 return get_pairs_filtered(system, distance, [types](Particle const &p) {
169 return std::ranges::any_of(
170 types, [target = p.type()](int const type) { return type == target; });
171 });
172}
173
174std::vector<PairInfo> non_bonded_loop_trace(System::System const &system,
175 int const rank) {
176 std::vector<PairInfo> pairs;
177 auto const pair_kernel = [&pairs, rank](Particle const &p1,
178 Particle const &p2,
179 Distance const &d) {
180 pairs.emplace_back(p1.id(), p2.id(), p1.pos(), p2.pos(), d.vec21, rank);
181 };
182 system.cell_structure->non_bonded_loop(pair_kernel);
183 return pairs;
184}
185
186std::vector<NeighborPIDs> get_neighbor_pids(System::System const &system) {
187 std::vector<NeighborPIDs> ret;
188 auto kernel = [&ret](Particle const &p,
189 std::vector<Particle const *> const &neighbors) {
190 std::vector<int> neighbor_pids;
191 neighbor_pids.reserve(neighbors.size());
192 for (auto const &neighbor : neighbors) {
193 neighbor_pids.emplace_back(neighbor->id());
194 }
195 ret.emplace_back(p.id(), neighbor_pids);
196 };
197 auto &cell_structure = *system.cell_structure;
198 for (auto const &p : cell_structure.local_particles()) {
199 kernel(p, get_interacting_neighbors(system, p));
200 }
201 return ret;
202}
@ HYBRID
Hybrid decomposition.
Vector implementation and trait types for boost qvm interoperability.
static auto get_interacting_neighbors(System::System const &system, Particle const &p)
Get pointers to all interacting neighbors of a central particle.
Definition cells.cpp:140
static auto get_pairs_filtered(System::System const &system, double const distance, Filter filter)
Get pairs of particles that are closer than a distance and fulfill a filter criterion.
Definition cells.cpp:61
std::optional< std::vector< int > > get_short_range_neighbors(System::System const &system, int const pid, double const distance)
Get ids of particles that are within a certain distance of another particle.
Definition cells.cpp:117
std::vector< PairInfo > non_bonded_loop_trace(System::System const &system, int const rank)
Returns pairs of particle ids, positions and distance as seen by the non-bonded loop.
Definition cells.cpp:174
std::vector< std::pair< int, int > > get_pairs_of_types(System::System const &system, double const distance, std::vector< int > const &types)
Get pairs closer than distance if both their types are in types.
Definition cells.cpp:165
std::vector< NeighborPIDs > get_neighbor_pids(System::System const &system)
Returns pairs of particle ids and neighbor particle id lists.
Definition cells.cpp:186
std::vector< std::pair< int, int > > get_pairs(System::System const &system, double const distance)
Get pairs closer than distance from the cells.
Definition cells.cpp:157
This file contains everything related to the global cell structure / cell system.
Main system class.
std::shared_ptr< CellStructure > cell_structure
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
Distance vector and length handed to pair kernels.
Struct holding all information for one particle.
Definition Particle.hpp:436
constexpr auto const & type() const
Definition Particle.hpp:459
constexpr auto const & id() const
Definition Particle.hpp:455