ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
accumulators.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-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#include "accumulators.hpp"
20
21#include <boost/range/algorithm/remove_if.hpp>
22#include <boost/range/numeric.hpp>
23
24#include <algorithm>
25#include <cassert>
26#include <limits>
27#include <vector>
28
29namespace Accumulators {
30namespace {
33 : frequency(acc->delta_N()), counter(1), acc(acc) {}
37};
38
39std::vector<AutoUpdateAccumulator> auto_update_accumulators;
40} // namespace
41
42void auto_update(boost::mpi::communicator const &comm, int steps) {
43 for (auto &acc : auto_update_accumulators) {
44 assert(steps <= acc.frequency);
45 acc.counter -= steps;
46 if (acc.counter <= 0) {
47 acc.acc->update(comm);
48 acc.counter = acc.frequency;
49 }
50
51 assert(acc.counter > 0);
52 }
53}
54
56 return boost::accumulate(auto_update_accumulators,
57 std::numeric_limits<int>::max(),
58 [](int a, AutoUpdateAccumulator const &acc) {
59 return std::min(a, acc.counter);
60 });
61}
62
63namespace detail {
64struct MatchPredicate {
65 AccumulatorBase const *m_acc;
66 template <typename T> bool operator()(T const &a) const {
67 return a.acc == m_acc;
68 }
69};
70} // namespace detail
71
73 assert(not auto_update_contains(acc));
74 auto_update_accumulators.emplace_back(acc);
75}
76
78 assert(auto_update_contains(acc));
79 auto const beg = auto_update_accumulators.begin();
80 auto const end = auto_update_accumulators.end();
81 auto_update_accumulators.erase(
82 std::remove_if(beg, end, detail::MatchPredicate{acc}), end);
83}
84
85bool auto_update_contains(AccumulatorBase const *acc) noexcept {
86 assert(acc);
87 auto const beg = auto_update_accumulators.begin();
88 auto const end = auto_update_accumulators.end();
89 return std::find_if(beg, end, detail::MatchPredicate{acc}) != end;
90}
91
92} // namespace Accumulators
std::vector< AutoUpdateAccumulator > auto_update_accumulators
void auto_update_add(AccumulatorBase *acc)
void auto_update(boost::mpi::communicator const &comm, int steps)
Update accumulators.
void auto_update_remove(AccumulatorBase *acc)
int auto_update_next_update()
bool auto_update_contains(AccumulatorBase const *acc) noexcept