Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
algorithms.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef SRC_PARTICLE_OBSERVABLES_ALGORITHMS_HPP
20#define SRC_PARTICLE_OBSERVABLES_ALGORITHMS_HPP
21
22/**
23 * @file
24 *
25 * Generic algorithms for the calculation of particle
26 * property derived observables.
27 */
28
29#include <algorithm>
30#include <numeric>
31#include <utility>
32#include <vector>
33
34namespace ParticleObservables {
35namespace detail {
36struct One {
37 template <class Particle> auto operator()(Particle const &p) const {
38 return 1;
39 }
40};
41
42template <class ValueOp, class WeightOp> struct WeightedSum {
43 template <class ParticleRange>
44 auto operator()(ParticleRange const &particles) const {
45 using particle_type = typename ParticleRange::value_type;
46 using value_op_type = decltype(ValueOp{}(std::declval<particle_type>()));
47 using weight_op_type = decltype(WeightOp{}(std::declval<particle_type>()));
48 auto func = [](auto const &sum, auto const &p) {
49 auto const w = WeightOp{}(p);
50 return std::make_pair(sum.first + ValueOp{}(p)*w, sum.second + w);
51 };
52
53 return std::accumulate(std::begin(particles), std::end(particles),
54 std::pair<value_op_type, weight_op_type>(), func);
55 }
56};
57} // namespace detail
58
59template <class ValueOp, class WeightOp> struct WeightedSum {
60 template <class ParticleRange>
61 auto operator()(ParticleRange const &particles) const {
62 auto const ws = detail::WeightedSum<ValueOp, WeightOp>()(particles);
63
64 return std::make_pair(ws.first, ws.second);
65 }
66
67 template <typename T> auto operator()(T const &acc, T const &val) const {
68 return std::make_pair(acc.first + val.first, acc.second + val.second);
69 }
70};
71
72template <class ValueOp> struct Sum {
73 template <class ParticleRange>
74 auto operator()(ParticleRange const &particles) const {
75 return std::make_pair(
76 detail::WeightedSum<ValueOp, detail::One>()(particles).first, 0.0);
77 }
78
79 template <typename T> auto operator()(T const &acc, T const &val) const {
80 return WeightedSum<ValueOp, detail::One>{}.operator()(acc, val);
81 }
82};
83
84template <class ValueOp, class WeightOp> struct WeightedAverage {
85 template <class ParticleRange>
86 auto operator()(ParticleRange const &particles) const {
87 auto const ws = detail::WeightedSum<ValueOp, WeightOp>()(particles);
88 return std::make_pair((ws.second) ? ws.first / ws.second : ws.first,
89 ws.second);
90 }
91
92 template <typename T> auto operator()(T const &acc, T const &val) const {
93 auto const value = acc.first * acc.second + val.first * val.second;
94 auto const weight = acc.second + val.second;
95 return std::make_pair((weight) ? value / weight : value, weight);
96 }
97};
98
99template <class ValueOp> struct Average {
100 template <class ParticleRange>
101 auto operator()(ParticleRange const &particles) const {
102 return WeightedAverage<ValueOp, detail::One>()(particles);
103 }
104
105 template <typename T> auto operator()(T const &acc, T const &val) const {
106 return WeightedAverage<ValueOp, detail::One>{}.operator()(acc, val);
107 }
108};
109
110template <class ValueOp> struct Map {
111 template <class ParticleRange>
112 auto operator()(ParticleRange const &particles) const {
113 using particle_type = typename ParticleRange::value_type;
114 using value_op_type = decltype(ValueOp{}(std::declval<particle_type>()));
115 std::vector<value_op_type> res;
116 std::ranges::transform(particles, std::back_inserter(res), ValueOp{});
117 return res;
118 }
119};
120} // namespace ParticleObservables
121#endif // SRC_PARTICLE_OBSERVABLES_ALGORITHMS_HPP
A range of particles.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
static double weight(int type, double r_cut, double k, double r)
Definition dpd.cpp:78
auto operator()(ParticleRange const &particles) const
auto operator()(T const &acc, T const &val) const
auto operator()(ParticleRange const &particles) const
auto operator()(ParticleRange const &particles) const
auto operator()(T const &acc, T const &val) const
auto operator()(ParticleRange const &particles) const
auto operator()(T const &acc, T const &val) const
auto operator()(ParticleRange const &particles) const
auto operator()(T const &acc, T const &val) const
Struct holding all information for one particle.
Definition Particle.hpp:395