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