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-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/range/algorithm/min_element.hpp>
45#include <boost/serialization/set.hpp>
46
47#include <algorithm>
48#include <functional>
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 *boost::min_element(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
118boost::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 = *boost::min_element(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::any_of(types.begin(), types.end(),
172 // NOLINTNEXTLINE(bugprone-exception-escape)
173 [p](int const type) { return p.type() == type; });
174 });
175}
176
177std::vector<PairInfo> non_bonded_loop_trace(System::System const &system,
178 int const rank) {
179 std::vector<PairInfo> pairs;
180 auto const pair_kernel = [&pairs, rank](Particle const &p1,
181 Particle const &p2,
182 Distance const &d) {
183 pairs.emplace_back(p1.id(), p2.id(), p1.pos(), p2.pos(), d.vec21, rank);
184 };
185 system.cell_structure->non_bonded_loop(pair_kernel);
186 return pairs;
187}
188
189std::vector<NeighborPIDs> get_neighbor_pids(System::System const &system) {
190 std::vector<NeighborPIDs> ret;
191 auto kernel = [&ret](Particle const &p,
192 std::vector<Particle const *> const &neighbors) {
193 std::vector<int> neighbor_pids;
194 neighbor_pids.reserve(neighbors.size());
195 for (auto const &neighbor : neighbors) {
196 neighbor_pids.emplace_back(neighbor->id());
197 }
198 ret.emplace_back(p.id(), neighbor_pids);
199 };
200 auto &cell_structure = *system.cell_structure;
201 for (auto const &p : cell_structure.local_particles()) {
202 kernel(p, get_interacting_neighbors(system, p));
203 }
204 return ret;
205}
@ 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::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:177
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
boost::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< NeighborPIDs > get_neighbor_pids(System::System const &system)
Returns pairs of particle ids and neighbor particle id lists.
Definition cells.cpp:189
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:26
Particles creation and deletion.
Distance vector and length handed to pair kernels.
Struct holding all information for one particle.
Definition Particle.hpp:393
auto const & id() const
Definition Particle.hpp:412