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
AutoUpdateAccumulators.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2024 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
21
22#include <boost/mpi/communicator.hpp>
23
24#include <algorithm>
25#include <cassert>
26#include <limits>
27#include <numeric>
28#include <vector>
29
30namespace Accumulators {
31
32void AutoUpdateAccumulators::operator()(boost::mpi::communicator const &comm,
33 int steps) {
34 for (auto &acc : m_accumulators) {
35 assert(steps <= acc.frequency);
36 acc.counter -= steps;
37 if (acc.counter <= 0) {
38 acc.acc->update(comm);
39 acc.counter = acc.frequency;
40 }
41
42 assert(acc.counter > 0);
43 }
44}
45
47 return std::accumulate(m_accumulators.begin(), m_accumulators.end(),
48 std::numeric_limits<int>::max(),
49 [](int a, AutoUpdateAccumulator const &acc) {
50 return std::min(a, acc.counter);
51 });
52}
53
54namespace detail {
55struct MatchPredicate {
56 AccumulatorBase const *m_acc;
57 template <typename T> bool operator()(T const &a) const {
58 return a.acc == m_acc;
59 }
60};
61} // namespace detail
62
64 assert(not contains(acc));
65 auto const *this_system = &get_system();
66 if (acc->has_same_system_handle(nullptr)) {
67 acc->override_system_handle(this_system);
68 } else if (not acc->has_same_system_handle(this_system)) {
69 throw std::runtime_error("This accumulator is bound to another system");
70 }
71 m_accumulators.emplace_back(acc);
72}
73
75 assert(contains(acc));
76 std::erase_if(m_accumulators, detail::MatchPredicate{acc});
77}
78
80 assert(acc);
81 return std::ranges::any_of(m_accumulators, detail::MatchPredicate{acc});
82}
83
84} // namespace Accumulators
void override_system_handle(::System::System const *system)
bool has_same_system_handle(::System::System const *system) const
bool contains(AccumulatorBase const *) const
void operator()(boost::mpi::communicator const &comm, int steps)
Update accumulators.