Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove more global variables #4950

Merged
merged 12 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/sphinx/analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ To obtain the cluster structure of a system, an instance of
To to create a cluster structure with above criterion::

import espressomd.cluster_analysis
cs = espressomd.cluster_analysis.ClusterStructure(distance_criterion=dc)
cs = espressomd.cluster_analysis.ClusterStructure(distance_criterion=dc, system=system)

In most cases, the cluster analysis is carried out by calling the
:any:`espressomd.cluster_analysis.ClusterStructure.run_for_all_pairs` method.
Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx/io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ capabilities. The usage is quite simple:
import espressomd.io
system = espressomd.System(box_l=[1, 1, 1])
# ... add particles here
mpiio = espressomd.io.mpiio.Mpiio()
mpiio = espressomd.io.mpiio.Mpiio(system=system)
mpiio.write("/tmp/mydata", positions=True, velocities=True, types=True, bonds=True)

Here, :file:`/tmp/mydata` is the prefix used to generate several files.
Expand Down
4 changes: 3 additions & 1 deletion doc/tutorials/ferrofluid/ferrofluid_part1.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,9 @@
"source": [
"# SOLUTION CELL\n",
"# Setup cluster analysis\n",
"cluster_structure = espressomd.cluster_analysis.ClusterStructure(pair_criterion=espressomd.pair_criteria.DistanceCriterion(cut_off=1.3 * LJ_SIGMA))"
"cluster_structure = espressomd.cluster_analysis.ClusterStructure(\n",
" system=system,\n",
" pair_criterion=espressomd.pair_criteria.DistanceCriterion(cut_off=1.3 * LJ_SIGMA))"
]
},
{
Expand Down
3 changes: 0 additions & 3 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@

add_library(
espresso_core SHARED
accumulators.cpp
bond_error.cpp
cells.cpp
collision.cpp
communication.cpp
constraints.cpp
dpd.cpp
energy.cpp
errorhandling.cpp
forces.cpp
ghosts.cpp
immersed_boundaries.cpp
integrate.cpp
npt.cpp
particle_node.cpp
Expand Down
87 changes: 0 additions & 87 deletions src/core/accumulators.cpp

This file was deleted.

40 changes: 0 additions & 40 deletions src/core/accumulators.hpp

This file was deleted.

30 changes: 23 additions & 7 deletions src/core/accumulators/AccumulatorBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,50 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CORE_ACCUMULATORS_ACCUMULATOR_BASE_HPP
#define CORE_ACCUMULATORS_ACCUMULATOR_BASE_HPP

#pragma once

#include <cassert>
#include <cstddef>
#include <string>
#include <vector>

// Forward declaration
// Forward declarations
namespace boost::mpi {
class communicator;
}
namespace System {
class System;
}

namespace Accumulators {

class AccumulatorBase {
public:
explicit AccumulatorBase(int delta_N = 1) : m_delta_N(delta_N) {}
AccumulatorBase(::System::System const *system, int delta_N)
: m_system(reinterpret_cast<void const *>(system)), m_delta_N(delta_N) {}
virtual ~AccumulatorBase() = default;

int &delta_N() { return m_delta_N; }
bool has_same_system_handle(::System::System const *system) const {
return reinterpret_cast<void const *>(system) == m_system;
}
void override_system_handle(::System::System const *system) {
assert(m_system == nullptr);
m_system = reinterpret_cast<void const *>(system);
}

virtual void update(boost::mpi::communicator const &comm) = 0;
/** Dimensions needed to reshape the flat array returned by the accumulator */
virtual std::vector<std::size_t> shape() const = 0;
/** Serialization of private members. */
virtual std::string get_internal_state() const = 0;
virtual void set_internal_state(std::string const &) = 0;

protected:
void const *m_system; ///< for bookkeeping purposes
private:
// Number of timesteps between automatic updates.
/// Number of time steps between automatic updates.
int m_delta_N;
};
} // namespace Accumulators

#endif
84 changes: 84 additions & 0 deletions src/core/accumulators/AutoUpdateAccumulators.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2016-2024 The ESPResSo project
*
* This file is part of ESPResSo.
*
* ESPResSo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ESPResSo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "AutoUpdateAccumulators.hpp"

#include <boost/mpi/communicator.hpp>

#include <algorithm>
#include <cassert>
#include <limits>
#include <numeric>
#include <vector>

namespace Accumulators {

void AutoUpdateAccumulators::operator()(boost::mpi::communicator const &comm,
int steps) {
for (auto &acc : m_accumulators) {
assert(steps <= acc.frequency);
acc.counter -= steps;
if (acc.counter <= 0) {
acc.acc->update(comm);
acc.counter = acc.frequency;
}

assert(acc.counter > 0);
}
}

int AutoUpdateAccumulators::next_update() const {
return std::accumulate(m_accumulators.begin(), m_accumulators.end(),
std::numeric_limits<int>::max(),
[](int a, AutoUpdateAccumulator const &acc) {
return std::min(a, acc.counter);
});
}

namespace detail {
struct MatchPredicate {
AccumulatorBase const *m_acc;
template <typename T> bool operator()(T const &a) const {
return a.acc == m_acc;
}
};
} // namespace detail

void AutoUpdateAccumulators::add(AccumulatorBase *acc) {
assert(not contains(acc));
auto const *this_system = &get_system();
if (acc->has_same_system_handle(nullptr)) {
acc->override_system_handle(this_system);
} else if (not acc->has_same_system_handle(this_system)) {
throw std::runtime_error("This accumulator is bound to another system");
}
m_accumulators.emplace_back(acc);
}

void AutoUpdateAccumulators::remove(AccumulatorBase *acc) {
assert(contains(acc));
std::erase_if(m_accumulators, detail::MatchPredicate{acc});
}

bool AutoUpdateAccumulators::contains(AccumulatorBase const *acc) const {
assert(acc);
return std::ranges::any_of(m_accumulators, detail::MatchPredicate{acc});
}

} // namespace Accumulators
55 changes: 55 additions & 0 deletions src/core/accumulators/AutoUpdateAccumulators.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2016-2024 The ESPResSo project
*
* This file is part of ESPResSo.
*
* ESPResSo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ESPResSo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "AccumulatorBase.hpp"

#include "system/Leaf.hpp"

namespace Accumulators {

class AutoUpdateAccumulators : public System::Leaf<AutoUpdateAccumulators> {
public:
/**
* @brief Update accumulators.
*
* Checks for all auto update accumulators if
* they need to be updated and if so does.
*
*/
void operator()(boost::mpi::communicator const &comm, int steps);
int next_update() const;
bool contains(AccumulatorBase const *) const;
void add(AccumulatorBase *);
void remove(AccumulatorBase *);

private:
struct AutoUpdateAccumulator {
explicit AutoUpdateAccumulator(AccumulatorBase *acc)
: frequency(acc->delta_N()), counter(1), acc(acc) {}
int frequency;
int counter;
AccumulatorBase *acc;
};

std::vector<AutoUpdateAccumulator> m_accumulators;
};

} // namespace Accumulators
1 change: 1 addition & 0 deletions src/core/accumulators/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
target_sources(
espresso_core
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Correlator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdateAccumulators.cpp
${CMAKE_CURRENT_SOURCE_DIR}/MeanVarianceCalculator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/TimeSeries.cpp)
Loading