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 "particle_node.hpp"
39#include "system/System.hpp"
40
41#include <utils/Vector.hpp>
42#include <utils/math/sqr.hpp>
43
44#include <boost/serialization/set.hpp>
45
46#include <algorithm>
47#include <optional>
48#include <stdexcept>
49#include <utility>
50#include <vector>
51
52/**
53 * @brief Get pairs of particles that are closer than a distance and fulfill a
54 * filter criterion.
55 *
56 * It uses link_cell to get pairs out of the cellsystem
57 * by a simple distance criterion and applies the filter on both particles.
58 *
59 * Pairs are sorted so that first.id < second.id
60 */
61template <class Filter>
63 double const distance, Filter filter) {
64 std::vector<std::pair<int, int>> ret;
65 auto const cutoff2 = Utils::sqr(distance);
66 auto const pair_kernel = [cutoff2, &filter, &ret](Particle const &p1,
67 Particle const &p2,
68 Distance const &d) {
69 if (d.dist2 < cutoff2 and filter(p1) and filter(p2)) {
70 auto pid1 = p1.id();
71 auto pid2 = p2.id();
72 if (pid1 > pid2) {
73 std::swap(pid1, pid2);
74 }
75 ret.emplace_back(pid1, pid2);
76 }
77 };
78
79 system.cell_structure->non_bonded_loop(pair_kernel);
80
81 return ret;
82}
83
84namespace detail {
85static auto get_max_neighbor_search_range(System::System const &system) {
86 auto const &cell_structure = *system.cell_structure;
87 return std::ranges::min(cell_structure.max_range());
88}
89static void search_distance_sanity_check_max_range(System::System const &system,
90 double const distance) {
91 /* get_pairs_filtered() finds pairs via the non_bonded_loop. The maximum
92 * finding range is therefore limited by the decomposition that is used.
93 */
94 auto const max_range = get_max_neighbor_search_range(system);
95 if (distance > max_range) {
96 throw std::domain_error("pair search distance " + std::to_string(distance) +
97 " bigger than the decomposition range " +
98 std::to_string(max_range));
99 }
100}
101static void
102search_distance_sanity_check_cell_structure(System::System const &system,
103 double const) {
104 auto const &cell_structure = *system.cell_structure;
105 if (cell_structure.decomposition_type() == CellStructureType::HYBRID) {
106 throw std::runtime_error("Cannot search for neighbors in the hybrid "
107 "decomposition cell system");
108 }
109}
110static void search_neighbors_sanity_checks(System::System const &system,
111 double const distance) {
112 search_distance_sanity_check_max_range(system, distance);
113 search_distance_sanity_check_cell_structure(system, distance);
114}
115} // namespace detail
116
117std::optional<std::vector<int>>
119 double const distance) {
120 detail::search_neighbors_sanity_checks(system, distance);
121 std::vector<int> ret;
122 auto const cutoff2 = Utils::sqr(distance);
123 auto const kernel = [cutoff2, &ret](Particle const &, Particle const &p2,
124 Utils::Vector3d const &vec) {
125 if (vec.norm2() < cutoff2) {
126 ret.emplace_back(p2.id());
127 }
128 };
129 auto &cell_structure = *system.cell_structure;
130 auto const p = cell_structure.get_local_particle(pid);
131 if (p and not p->is_ghost()) {
132 cell_structure.run_on_particle_short_range_neighbors(*p, kernel);
133 return {ret};
134 }
135 return {};
136}
137
138/**
139 * @brief Get pointers to all interacting neighbors of a central particle.
140 */
142 Particle const &p) {
143 auto &cell_structure = *system.cell_structure;
144 auto const distance = std::ranges::min(cell_structure.max_range());
145 detail::search_neighbors_sanity_checks(system, distance);
146 std::vector<Particle const *> ret;
147 auto const cutoff2 = Utils::sqr(distance);
148 auto const kernel = [cutoff2, &ret](Particle const &, Particle const &p2,
149 Utils::Vector3d const &vec) {
150 if (vec.norm2() < cutoff2) {
151 ret.emplace_back(&p2);
152 }
153 };
154 cell_structure.run_on_particle_short_range_neighbors(p, kernel);
155 return ret;
156}
157
158std::vector<std::pair<int, int>> get_pairs(System::System const &system,
159 double const distance) {
160 detail::search_neighbors_sanity_checks(system, distance);
161 return get_pairs_filtered(system, distance,
162 [](Particle const &) { return true; });
163}
164
165std::vector<std::pair<int, int>>
166get_pairs_of_types(System::System const &system, double const distance,
167 std::vector<int> const &types) {
168 detail::search_neighbors_sanity_checks(system, distance);
169 return get_pairs_filtered(system, distance, [types](Particle const &p) {
170 return std::ranges::any_of(
171 types, [target = p.type()](int const type) { return type == target; });
172 });
173}
174
175std::vector<PairInfo> non_bonded_loop_trace(System::System const &system,
176 int const rank) {
177 std::vector<PairInfo> pairs;
178 auto const pair_kernel = [&pairs, rank](Particle const &p1,
179 Particle const &p2,
180 Distance const &d) {
181 pairs.emplace_back(p1.id(), p2.id(), p1.pos(), p2.pos(), d.vec21, rank);
182 };
183 system.cell_structure->non_bonded_loop(pair_kernel);
184 return pairs;
185}
186
187std::vector<NeighborPIDs> get_neighbor_pids(System::System const &system) {
188 std::vector<NeighborPIDs> ret;
189 auto kernel = [&ret](Particle const &p,
190 std::vector<Particle const *> const &neighbors) {
191 std::vector<int> neighbor_pids;
192 neighbor_pids.reserve(neighbors.size());
193 for (auto const &neighbor : neighbors) {
194 neighbor_pids.emplace_back(neighbor->id());
195 }
196 ret.emplace_back(p.id(), neighbor_pids);
197 };
198 auto &cell_structure = *system.cell_structure;
199 for (auto const &p : cell_structure.local_particles()) {
200 kernel(p, get_interacting_neighbors(system, p));
201 }
202 return ret;
203}
@ 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:141
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:62
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:118
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:175
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:166
std::vector< NeighborPIDs > get_neighbor_pids(System::System const &system)
Returns pairs of particle ids and neighbor particle id lists.
Definition cells.cpp:187
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:158
This file contains everything related to the global cell structure / cell system.
Main system class.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
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
Particles creation and deletion.
Distance vector and length handed to pair kernels.
Struct holding all information for one particle.
Definition Particle.hpp:435
auto const & type() const
Definition Particle.hpp:458
auto const & id() const
Definition Particle.hpp:454