diff --git a/src/core/MpiCallbacks.hpp b/src/core/MpiCallbacks.hpp index 595317f032c..6c28cf079f1 100644 --- a/src/core/MpiCallbacks.hpp +++ b/src/core/MpiCallbacks.hpp @@ -75,9 +75,9 @@ constexpr auto ignore = Ignore{}; /** Return value from one rank */ struct OneRank {}; constexpr auto one_rank = OneRank{}; -/** Return value from master rank */ -struct MasterRank {}; -constexpr auto master_rank = MasterRank{}; +/** Return value from the head node */ +struct MainRank {}; +constexpr auto main_rank = MainRank{}; /** Reduce return value over all ranks */ struct Reduction {}; constexpr auto reduction = Reduction{}; @@ -224,21 +224,21 @@ struct callback_one_rank_t final : public callback_concept_t { }; /** - * @brief Callback with a return value from the master rank. + * @brief Callback with a return value from the head node. * * This is an implementation of a callback for a specific callable * @p F and a set of arguments to call it with, where the value from - * the master rank is returned. + * the head node is returned. */ template -struct callback_master_rank_t final : public callback_concept_t { +struct callback_main_rank_t final : public callback_concept_t { F m_f; - callback_master_rank_t(callback_master_rank_t const &) = delete; - callback_master_rank_t(callback_master_rank_t &&) = delete; + callback_main_rank_t(callback_main_rank_t const &) = delete; + callback_main_rank_t(callback_main_rank_t &&) = delete; template - explicit callback_master_rank_t(FRef &&f) : m_f(std::forward(f)) {} + explicit callback_main_rank_t(FRef &&f) : m_f(std::forward(f)) {} void operator()(boost::mpi::communicator const &comm, boost::mpi::packed_iarchive &ia) const override { (void)detail::invoke(m_f, ia); @@ -337,9 +337,8 @@ auto make_model(Result::OneRank, R (*f_ptr)(Args...)) { } template -auto make_model(Result::MasterRank, R (*f_ptr)(Args...)) { - return std::make_unique>( - f_ptr); +auto make_model(Result::MainRank, R (*f_ptr)(Args...)) { + return std::make_unique>(f_ptr); } } // namespace detail @@ -541,7 +540,7 @@ class MpiCallbacks { /* Check if callback exists */ if (m_callback_map.find(id) == m_callback_map.end()) { - throw std::out_of_range("Callback does not exists."); + throw std::out_of_range("Callback does not exist."); } /* Send request to worker nodes */ @@ -557,15 +556,12 @@ class MpiCallbacks { public: /** - * @brief call a callback. + * @brief Call a callback on worker nodes. * - * Call a static callback by pointer. - * The method can only be called on the head node - * and has the prerequisite that the other nodes are - * in the MPI loop. Also the function has to be previously - * registered e.g. with the @ref REGISTER_CALLBACK macro. * The callback is **not** called on the head node. * + * This method can only be called on the head node. + * * @param fp Pointer to the function to call. * @param args Arguments for the callback. */ @@ -580,14 +576,11 @@ class MpiCallbacks { } /** - * @brief call a callback. + * @brief Call a callback on all nodes. * - * Call a static callback by pointer. - * The method can only be called on the head node - * and has the prerequisite that the other nodes are - * in the MPI loop. Also the function has to be previously - * registered e.g. with the @ref REGISTER_CALLBACK macro. - * The callback is called on the head node. + * This calls a callback on all nodes, including the head node. + * + * This method can only be called on the head node. * * @param fp Pointer to the function to call. * @param args Arguments for the callback. @@ -682,7 +675,7 @@ class MpiCallbacks { * This method can only be called on the head node. */ template - auto call(Result::MasterRank, R (*fp)(Args...), ArgRef... args) const + auto call(Result::MainRank, R (*fp)(Args...), ArgRef... args) const -> std::remove_reference_t { const int id = m_func_ptr_to_id.at(reinterpret_cast(fp)); @@ -692,13 +685,13 @@ class MpiCallbacks { } /** - * @brief Mpi slave loop. + * @brief Start the MPI loop. * - * This is the callback loop for the slaves. They block + * This is the callback loop for the worker nodes. They block * on the MPI call and wait for a new callback request - * coming from the master. - * This should be run on the slaves and must be running - * so that the master can issue call(). + * coming from the head node. + * This should be run on the worker nodes and must be running + * so that the head node can issue call(). */ void loop() const { for (;;) { @@ -718,9 +711,9 @@ class MpiCallbacks { } /** - * @brief Abort mpi loop. + * @brief Abort the MPI loop. * - * Make the slaves exit the MPI loop. + * Make the worker nodes exit the MPI loop. */ void abort_loop() { call(LOOP_ABORT); } @@ -864,10 +857,10 @@ class RegisterCallback { * * @param cb A function */ -#define REGISTER_CALLBACK_MASTER_RANK(cb) \ +#define REGISTER_CALLBACK_MAIN_RANK(cb) \ namespace Communication { \ static ::Communication::RegisterCallback \ - register_master_rank_##cb(::Communication::Result::MasterRank{}, &(cb)); \ + register_main_rank_##cb(::Communication::Result::MainRank{}, &(cb)); \ } /**@}*/ diff --git a/src/core/PartCfg.hpp b/src/core/PartCfg.hpp index ac782404724..3f05c87f7bd 100644 --- a/src/core/PartCfg.hpp +++ b/src/core/PartCfg.hpp @@ -25,12 +25,12 @@ #include /** - * @brief Particle cache on the master. + * @brief Particle cache on the head node. * * This class implements cached access to all particles in a - * particle range on the master node. + * particle range on the head node. * This implementation fetches all particles to - * the master on first access. Updates of the particle data are + * the head node on first access. Updates of the particle data are * triggered automatically on access. The data in the cache * is invalidated automatically on_particle_change, and then * updated on the next access. @@ -101,7 +101,7 @@ class PartCfg { * * This triggers a global update. All nodes * sort their particle by id, and send them - * to the master. + * to the head node. */ private: void update(); diff --git a/src/core/RuntimeErrorCollector.cpp b/src/core/RuntimeErrorCollector.cpp index 2e917d14777..ef5f3f68088 100644 --- a/src/core/RuntimeErrorCollector.cpp +++ b/src/core/RuntimeErrorCollector.cpp @@ -124,7 +124,7 @@ std::vector RuntimeErrorCollector::gather() { return all_errors; } -void RuntimeErrorCollector::gatherSlave() { +void RuntimeErrorCollector::gather_local() { Utils::Mpi::gather_buffer(m_errors, m_comm); this->clear(); diff --git a/src/core/RuntimeErrorCollector.hpp b/src/core/RuntimeErrorCollector.hpp index 84d5188928d..74d2c0600f4 100644 --- a/src/core/RuntimeErrorCollector.hpp +++ b/src/core/RuntimeErrorCollector.hpp @@ -74,7 +74,7 @@ class RuntimeErrorCollector { void clear(); std::vector gather(); - void gatherSlave(); + void gather_local(); const boost::mpi::communicator &comm() const { return m_comm; } diff --git a/src/core/bonded_interactions/bonded_interaction_data.cpp b/src/core/bonded_interactions/bonded_interaction_data.cpp index db5f87a543a..a4daab9918f 100644 --- a/src/core/bonded_interactions/bonded_interaction_data.cpp +++ b/src/core/bonded_interactions/bonded_interaction_data.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see . */ #include "bonded_interaction_data.hpp" -#include "interactions.hpp" +#include "event.hpp" #include #include @@ -30,6 +30,8 @@ BondedInteractionsMap bonded_ia_params; +void mpi_update_cell_system_ia_range_local() { on_short_range_ia_change(); } + /** Visitor to get the bond cutoff from the bond parameter variant */ class BondCutoff : public boost::static_visitor { public: diff --git a/src/core/bonded_interactions/bonded_interaction_data.hpp b/src/core/bonded_interactions/bonded_interaction_data.hpp index b882005e405..f243eea4ba0 100644 --- a/src/core/bonded_interactions/bonded_interaction_data.hpp +++ b/src/core/bonded_interactions/bonded_interaction_data.hpp @@ -142,6 +142,9 @@ class BondedInteractionsMap { key_type next_key = static_cast(0); }; +/** Notify the cell system about changes to the maximal interaction range. */ +void mpi_update_cell_system_ia_range_local(); + /** Field containing the parameters of the bonded ia types */ extern BondedInteractionsMap bonded_ia_params; diff --git a/src/core/bonded_interactions/bonded_interaction_utils.hpp b/src/core/bonded_interactions/bonded_interaction_utils.hpp index a005d47e443..ada4adbeb88 100644 --- a/src/core/bonded_interactions/bonded_interaction_utils.hpp +++ b/src/core/bonded_interactions/bonded_interaction_utils.hpp @@ -20,7 +20,6 @@ #define _BONDED_INTERACTION_UTILS_HPP #include "bonded_interaction_data.hpp" -#include "interactions.hpp" #include "BondList.hpp" #include "Particle.hpp" diff --git a/src/core/bonded_interactions/rigid_bond.cpp b/src/core/bonded_interactions/rigid_bond.cpp index 9e0663bb6e1..7a6a197433e 100644 --- a/src/core/bonded_interactions/rigid_bond.cpp +++ b/src/core/bonded_interactions/rigid_bond.cpp @@ -24,7 +24,6 @@ */ #include "rigid_bond.hpp" -#include "communication.hpp" int n_rigidbonds = 0; @@ -33,16 +32,5 @@ RigidBond::RigidBond(double d, double p_tol, double v_tol) { this->p_tol = 2.0 * p_tol; this->v_tol = v_tol; - if (this_node == 0) - mpi_set_n_rigidbonds(n_rigidbonds + 1); + n_rigidbonds++; } - -void mpi_set_n_rigidbonds_local(int n_rigidbonds) { - ::n_rigidbonds = n_rigidbonds; -} - -REGISTER_CALLBACK(mpi_set_n_rigidbonds_local) - -void mpi_set_n_rigidbonds(int n_rigidbonds) { - mpi_call_all(mpi_set_n_rigidbonds_local, n_rigidbonds); -} \ No newline at end of file diff --git a/src/core/bonded_interactions/rigid_bond.hpp b/src/core/bonded_interactions/rigid_bond.hpp index a4ddd45acbb..0253eade9a3 100644 --- a/src/core/bonded_interactions/rigid_bond.hpp +++ b/src/core/bonded_interactions/rigid_bond.hpp @@ -63,5 +63,4 @@ struct RigidBond { } }; -void mpi_set_n_rigidbonds(int n_rigidbonds); -#endif \ No newline at end of file +#endif diff --git a/src/core/bonded_interactions/thermalized_bond.cpp b/src/core/bonded_interactions/thermalized_bond.cpp index e935e895f04..83fb30ea6fb 100644 --- a/src/core/bonded_interactions/thermalized_bond.cpp +++ b/src/core/bonded_interactions/thermalized_bond.cpp @@ -24,7 +24,6 @@ */ #include "thermalized_bond.hpp" -#include "communication.hpp" #include "event.hpp" int n_thermalized_bonds = 0; @@ -43,17 +42,6 @@ ThermalizedBond::ThermalizedBond(double temp_com, double gamma_com, pref1_dist = -1.; pref2_dist = -1.; - if (this_node == 0) - mpi_set_n_thermalized_bonds(n_thermalized_bonds + 1); -} - -void mpi_set_n_thermalized_bonds_local(int n_thermalized_bonds) { - ::n_thermalized_bonds = n_thermalized_bonds; + n_thermalized_bonds++; on_thermostat_param_change(); } - -REGISTER_CALLBACK(mpi_set_n_thermalized_bonds_local) - -void mpi_set_n_thermalized_bonds(int n_thermalized_bonds) { - mpi_call_all(mpi_set_n_thermalized_bonds_local, n_thermalized_bonds); -} diff --git a/src/core/bonded_interactions/thermalized_bond.hpp b/src/core/bonded_interactions/thermalized_bond.hpp index 4da3ce66f9a..e838231b84e 100644 --- a/src/core/bonded_interactions/thermalized_bond.hpp +++ b/src/core/bonded_interactions/thermalized_bond.hpp @@ -134,5 +134,4 @@ ThermalizedBond::forces(Particle const &p1, Particle const &p2, return std::make_tuple(force1, force2); } -void mpi_set_n_thermalized_bonds(int n_thermalized_bonds); #endif diff --git a/src/core/cells.cpp b/src/core/cells.cpp index bacfe35415b..63b961d8075 100644 --- a/src/core/cells.cpp +++ b/src/core/cells.cpp @@ -111,32 +111,26 @@ std::vector non_bonded_loop_trace() { return ret; } -std::vector> get_pairs(double const distance) { - return get_pairs_filtered(distance, [](Particle const &p) { return true; }); +static auto mpi_get_pairs_local(double const distance) { + auto pairs = + get_pairs_filtered(distance, [](Particle const &) { return true; }); + Utils::Mpi::gather_buffer(pairs, comm_cart); + return pairs; } -std::vector> -get_pairs_of_types(double const distance, std::vector const &types) { - return get_pairs_filtered(distance, [types](Particle const &p) { +REGISTER_CALLBACK_MAIN_RANK(mpi_get_pairs_local) + +static auto mpi_get_pairs_of_types_local(double const distance, + std::vector const &types) { + auto pairs = get_pairs_filtered(distance, [types](Particle const &p) { return std::any_of(types.begin(), types.end(), [p](int const type) { return p.p.type == type; }); }); + Utils::Mpi::gather_buffer(pairs, comm_cart); + return pairs; } -void get_pairs_local(double const distance) { - auto local_pairs = get_pairs(distance); - Utils::Mpi::gather_buffer(local_pairs, comm_cart); -} - -REGISTER_CALLBACK(get_pairs_local) - -void get_pairs_of_types_local(double const distance, - std::vector const &types) { - auto local_pairs = get_pairs_of_types(distance, types); - Utils::Mpi::gather_buffer(local_pairs, comm_cart); -} - -REGISTER_CALLBACK(get_pairs_of_types_local) +REGISTER_CALLBACK_MAIN_RANK(mpi_get_pairs_of_types_local) namespace detail { void search_distance_sanity_check(double const distance) { @@ -153,22 +147,18 @@ void search_distance_sanity_check(double const distance) { std::vector> mpi_get_pairs(double const distance) { detail::search_distance_sanity_check(distance); - mpi_call(get_pairs_local, distance); - auto pairs = get_pairs(distance); - Utils::Mpi::gather_buffer(pairs, comm_cart); - return pairs; + return mpi_call(::Communication::Result::main_rank, mpi_get_pairs_local, + distance); } std::vector> mpi_get_pairs_of_types(double const distance, std::vector const &types) { detail::search_distance_sanity_check(distance); - mpi_call(get_pairs_of_types_local, distance, types); - auto pairs = get_pairs_of_types(distance, types); - Utils::Mpi::gather_buffer(pairs, comm_cart); - return pairs; + return mpi_call(::Communication::Result::main_rank, + mpi_get_pairs_of_types_local, distance, types); } -void non_bonded_loop_trace_local() { +static void non_bonded_loop_trace_local() { auto pairs = non_bonded_loop_trace(); Utils::Mpi::gather_buffer(pairs, comm_cart); } @@ -182,7 +172,7 @@ std::vector mpi_non_bonded_loop_trace() { return pairs; } -void mpi_resort_particles_local(int global_flag, int) { +static void mpi_resort_particles_local(int global_flag) { cell_structure.resort_particles(global_flag); boost::mpi::gather( @@ -192,7 +182,7 @@ void mpi_resort_particles_local(int global_flag, int) { REGISTER_CALLBACK(mpi_resort_particles_local) std::vector mpi_resort_particles(int global_flag) { - mpi_call(mpi_resort_particles_local, global_flag, 0); + mpi_call(mpi_resort_particles_local, global_flag); cell_structure.resort_particles(global_flag); clear_particle_node(); diff --git a/src/core/communication.hpp b/src/core/communication.hpp index d3401305597..724f2e37dfa 100644 --- a/src/core/communication.hpp +++ b/src/core/communication.hpp @@ -26,25 +26,22 @@ * It is the header file for communication.cpp. * * The asynchronous MPI communication is used during the script - * evaluation. Except for the master node that interprets the interface - * script, all other nodes wait in mpi_loop() for the master node to - * issue an action using mpi_call(). mpi_loop() immediately - * executes an MPI_Bcast and therefore waits for the master node to - * broadcast a command, which is done by mpi_call(). The request - * consists of a callback function and two arbitrary integers. If - * applicable, the first integer is the node number of the slave - * this request is dedicated to. + * evaluation. Except for the head node that interprets the interface + * script, all other nodes wait in @ref mpi_loop() for the head node to + * issue an action using @ref mpi_call(). @ref mpi_loop() immediately + * executes an @c MPI_Bcast and therefore waits for the head node to + * broadcast a command, which is done by @ref mpi_call(). The request + * consists of a callback function with an arbitrary number of arguments. * * To add new actions (e.g. to implement new interface functionality), do the * following: - * - write the @c mpi_* function that is executed on the master - * - write the @c mpi_*_slave function - * - register your slave function with one of the @c REGISTER_CALLBACK macros + * - write the @c mpi_* function that is executed on the head node + * - write the @c mpi_*_local function that is executed on worker nodes + * - register the local function with one of the @c REGISTER_CALLBACK macros * * After this, your procedure is free to do anything. However, it has - * to be in (MPI) sync with what your new @c mpi_*_slave does. This - * procedure is called immediately after the broadcast with the - * arbitrary integer as parameter. + * to be in (MPI) sync with what your new @c mpi_*_local does. This + * procedure is called immediately after the broadcast. */ #include "MpiCallbacks.hpp" @@ -77,44 +74,44 @@ MpiCallbacks &mpiCallbacks(); /************************************************** * for every procedure requesting a MPI negotiation, - * a slave exists which processes this request on - * the slave nodes. It is denoted by *_slave. + * a callback exists which processes this request on + * the worker nodes. It is denoted by *_local. **************************************************/ /** Initialize MPI. */ std::shared_ptr mpi_init(int argc = 0, char **argv = nullptr); -/** @brief Call a slave function. - * @tparam Args Slave function argument types - * @tparam ArgRef Slave function argument types - * @param fp Slave function - * @param args Slave function arguments +/** @brief Call a local function. + * @tparam Args Local function argument types + * @tparam ArgRef Local function argument types + * @param fp Local function + * @param args Local function arguments */ template void mpi_call(void (*fp)(Args...), ArgRef &&... args) { Communication::mpiCallbacks().call(fp, std::forward(args)...); } -/** @brief Call a slave function. - * @tparam Args Slave function argument types - * @tparam ArgRef Slave function argument types - * @param fp Slave function - * @param args Slave function arguments +/** @brief Call a local function. + * @tparam Args Local function argument types + * @tparam ArgRef Local function argument types + * @param fp Local function + * @param args Local function arguments */ template void mpi_call_all(void (*fp)(Args...), ArgRef &&... args) { Communication::mpiCallbacks().call_all(fp, std::forward(args)...); } -/** @brief Call a slave function. +/** @brief Call a local function. * @tparam Tag Any tag type defined in @ref Communication::Result - * @tparam R Return type of the slave function - * @tparam Args Slave function argument types - * @tparam ArgRef Slave function argument types + * @tparam R Return type of the local function + * @tparam Args Local function argument types + * @tparam ArgRef Local function argument types * @param tag Reduction strategy - * @param fp Slave function - * @param args Slave function arguments + * @param fp Local function + * @param args Local function arguments */ template auto mpi_call(Tag tag, R (*fp)(Args...), ArgRef &&... args) { @@ -122,16 +119,16 @@ auto mpi_call(Tag tag, R (*fp)(Args...), ArgRef &&... args) { std::forward(args)...); } -/** @brief Call a slave function. +/** @brief Call a local function. * @tparam Tag Any tag type defined in @ref Communication::Result * @tparam TagArg Types of arguments to @p Tag - * @tparam R Return type of the slave function - * @tparam Args Slave function argument types - * @tparam ArgRef Slave function argument types + * @tparam R Return type of the local function + * @tparam Args Local function argument types + * @tparam ArgRef Local function argument types * @param tag Reduction strategy * @param tag_arg Arguments to the reduction strategy - * @param fp Slave function - * @param args Slave function arguments + * @param fp Local function + * @param args Local function arguments */ template auto mpi_call(Tag tag, TagArg &&tag_arg, R (*fp)(Args...), ArgRef &&... args) { @@ -139,7 +136,7 @@ auto mpi_call(Tag tag, TagArg &&tag_arg, R (*fp)(Args...), ArgRef &&... args) { fp, std::forward(args)...); } -/** Process requests from master node. Slave nodes main loop. */ +/** Process requests from head node. Worker nodes main loop. */ void mpi_loop(); namespace Communication { diff --git a/src/core/cuda_init.cpp b/src/core/cuda_init.cpp index ce6b537b0ab..f39dc4d84ea 100644 --- a/src/core/cuda_init.cpp +++ b/src/core/cuda_init.cpp @@ -51,7 +51,7 @@ struct CompareDevices { } }; -/** Gather list of CUDA devices on all nodes on the master node. +/** Gather list of CUDA devices on all nodes on the head node. * It relies on MPI_Get_processor_name() to get a unique identifier * of the physical node, as opposed to the logical rank of which there can * be more than one per node. @@ -59,7 +59,7 @@ struct CompareDevices { static std::vector mpi_cuda_gather_gpus_local() { /* List of local devices */ std::vector devices_local; - /* Global unique device list (only relevant on master) */ + /* Global unique device list (only relevant on the head node) */ std::vector devices_global; int n_devices; @@ -113,9 +113,9 @@ static std::vector mpi_cuda_gather_gpus_local() { std::inserter(devices_global, devices_global.begin())); delete[] n_gpu_array; } else { - /* Send number of devices to master */ + /* Send number of devices to head node */ MPI_Gather(&n_gpus, 1, MPI_INT, nullptr, 1, MPI_INT, 0, MPI_COMM_WORLD); - /* Send devices to master */ + /* Send devices to head node */ for (auto const &device : devices_local) { MPI_Send(&device, sizeof(EspressoGpuDevice), MPI_BYTE, 0, 0, MPI_COMM_WORLD); @@ -124,11 +124,10 @@ static std::vector mpi_cuda_gather_gpus_local() { return devices_global; } -REGISTER_CALLBACK_MASTER_RANK(mpi_cuda_gather_gpus_local) +REGISTER_CALLBACK_MAIN_RANK(mpi_cuda_gather_gpus_local) std::vector cuda_gather_gpus() { - return mpi_call(Communication::Result::master_rank, - mpi_cuda_gather_gpus_local); + return mpi_call(Communication::Result::main_rank, mpi_cuda_gather_gpus_local); } #endif /* CUDA */ diff --git a/src/core/cuda_interface.cpp b/src/core/cuda_interface.cpp index 5cca8d46705..7d8353efe68 100644 --- a/src/core/cuda_interface.cpp +++ b/src/core/cuda_interface.cpp @@ -153,7 +153,7 @@ void cuda_mpi_send_forces(const ParticleRange &particles, add_forces_and_torques(particles, buffer_forces, buffer_torques); } else { - /* Scatter forces to slaves */ + /* Scatter forces */ Utils::Mpi::scatter_buffer(host_forces.data(), n_elements, comm_cart); #ifdef ROTATION Utils::Mpi::scatter_buffer(host_torques.data(), n_elements, comm_cart); @@ -163,7 +163,7 @@ void cuda_mpi_send_forces(const ParticleRange &particles, } } -void cuda_bcast_global_part_params_local(int, int) { +static void cuda_bcast_global_part_params_local() { MPI_Bcast(gpu_get_global_particle_vars_pointer_host(), sizeof(CUDA_global_part_vars), MPI_BYTE, 0, comm_cart); espressoSystemInterface.requestParticleStructGpu(); @@ -172,7 +172,7 @@ void cuda_bcast_global_part_params_local(int, int) { REGISTER_CALLBACK(cuda_bcast_global_part_params_local) void cuda_bcast_global_part_params() { - mpi_call_all(cuda_bcast_global_part_params_local, -1, -1); + mpi_call_all(cuda_bcast_global_part_params_local); } #endif /* ifdef CUDA */ diff --git a/src/core/cuda_interface.hpp b/src/core/cuda_interface.hpp index d53243807d0..dcff4826a4e 100644 --- a/src/core/cuda_interface.hpp +++ b/src/core/cuda_interface.hpp @@ -125,15 +125,15 @@ void cuda_mpi_get_particles( void copy_part_data_to_gpu(ParticleRange particles); /** - * @brief Distribute forces to the slaves, and add them to the particles. + * @brief Distribute forces to the worker nodes, and add them to the particles. * * @param particles The particles for which the forces (and torques) should * be added to. * @param host_forces The forces as flat array of size 3 * particles.size(), - * only relevant on the master. + * only relevant on the head node. * @param host_torques The torques as flat array of size 3 * particles.size(), * this is only touched if ROTATION is active. Only - * relevant on the master. + * relevant on the head node. * * This is a collective call. */ diff --git a/src/core/electrostatics_magnetostatics/ScafacosContext.cpp b/src/core/electrostatics_magnetostatics/ScafacosContext.cpp index 59cbb127769..d927d34f503 100644 --- a/src/core/electrostatics_magnetostatics/ScafacosContext.cpp +++ b/src/core/electrostatics_magnetostatics/ScafacosContext.cpp @@ -176,16 +176,16 @@ double ScafacosContextDipoles::long_range_energy() { } #endif -static void set_r_cut_and_tune_local_worker(double r_cut) { - set_r_cut_and_tune_local(r_cut); +static void set_r_cut_and_tune_local(double r_cut) { + set_r_cut_and_tune(r_cut); } -REGISTER_CALLBACK(set_r_cut_and_tune_local_worker) +REGISTER_CALLBACK(set_r_cut_and_tune_local) /** Determine runtime for a specific cutoff */ static double time_r_cut(double r_cut) { /* Set cutoff to time */ - mpi_call_all(set_r_cut_and_tune_local_worker, r_cut); + mpi_call_all(set_r_cut_and_tune_local, r_cut); return time_force_calc(10); } @@ -238,7 +238,7 @@ void ScafacosContextCoulomb::tune() { } } -void ScafacosContextCoulomb::set_r_cut_and_tune_local(double r_cut) { +void ScafacosContextCoulomb::set_r_cut_and_tune(double r_cut) { update_particle_data(); set_r_cut(r_cut); Scafacos::tune(charges, positions); diff --git a/src/core/electrostatics_magnetostatics/ScafacosContext.hpp b/src/core/electrostatics_magnetostatics/ScafacosContext.hpp index e22d1039b4a..dd9293c7f2b 100644 --- a/src/core/electrostatics_magnetostatics/ScafacosContext.hpp +++ b/src/core/electrostatics_magnetostatics/ScafacosContext.hpp @@ -77,7 +77,7 @@ struct ScafacosContextCoulomb : ScafacosContext { update_particle_forces(); } void tune(); - void set_r_cut_and_tune_local(double r_cut); + void set_r_cut_and_tune(double r_cut); private: /** Inputs */ diff --git a/src/core/electrostatics_magnetostatics/common.cpp b/src/core/electrostatics_magnetostatics/common.cpp index d0a1bf21af8..25d98eb0683 100644 --- a/src/core/electrostatics_magnetostatics/common.cpp +++ b/src/core/electrostatics_magnetostatics/common.cpp @@ -30,7 +30,7 @@ #include -void mpi_bcast_coulomb_params_local(int, int) { +static void mpi_bcast_coulomb_params_local() { #ifdef ELECTROSTATICS MPI_Bcast(&coulomb, sizeof(Coulomb_parameters), MPI_BYTE, 0, comm_cart); Coulomb::bcast_coulomb_params(); @@ -51,6 +51,6 @@ REGISTER_CALLBACK(mpi_bcast_coulomb_params_local) void mpi_bcast_coulomb_params() { #if defined(ELECTROSTATICS) || defined(DIPOLES) - mpi_call_all(mpi_bcast_coulomb_params_local, -1, -1); + mpi_call_all(mpi_bcast_coulomb_params_local); #endif } diff --git a/src/core/electrostatics_magnetostatics/coulomb.cpp b/src/core/electrostatics_magnetostatics/coulomb.cpp index 4a87c5c5f93..525bca1eefa 100644 --- a/src/core/electrostatics_magnetostatics/coulomb.cpp +++ b/src/core/electrostatics_magnetostatics/coulomb.cpp @@ -84,11 +84,12 @@ Utils::Vector9d calc_pressure_long_range(const ParticleRange &particles) { return {}; } -void sanity_checks(int &state) { +bool sanity_checks() { + bool failed = false; switch (coulomb.method) { case COULOMB_MMM1D: if (MMM1D_sanity_checks()) - state = 0; + failed = true; break; #ifdef P3M case COULOMB_ELC_P3M: @@ -96,18 +97,19 @@ void sanity_checks(int &state) { ELC_sanity_checks(elc_params); } catch (std::runtime_error const &err) { runtimeErrorMsg() << err.what(); - state = 0; + failed = true; } // fall through case COULOMB_P3M_GPU: case COULOMB_P3M: if (p3m_sanity_checks()) - state = 0; + failed = true; break; #endif default: break; } + return failed; } double cutoff(const Utils::Vector3d &box_l) { diff --git a/src/core/electrostatics_magnetostatics/coulomb.hpp b/src/core/electrostatics_magnetostatics/coulomb.hpp index 3cd546d1f32..afd99bccaa6 100644 --- a/src/core/electrostatics_magnetostatics/coulomb.hpp +++ b/src/core/electrostatics_magnetostatics/coulomb.hpp @@ -62,7 +62,7 @@ extern Coulomb_parameters coulomb; namespace Coulomb { Utils::Vector9d calc_pressure_long_range(const ParticleRange &particles); -void sanity_checks(int &state); +bool sanity_checks(); double cutoff(const Utils::Vector3d &box_l); void deactivate(); diff --git a/src/core/electrostatics_magnetostatics/dipole.cpp b/src/core/electrostatics_magnetostatics/dipole.cpp index 3df296b581f..629d13bc8cf 100644 --- a/src/core/electrostatics_magnetostatics/dipole.cpp +++ b/src/core/electrostatics_magnetostatics/dipole.cpp @@ -64,7 +64,8 @@ void calc_pressure_long_range() { } } -void nonbonded_sanity_check(int &state) { +bool sanity_checks() { + bool failed = false; #ifdef DP3M try { switch (dipole.method) { @@ -73,7 +74,7 @@ void nonbonded_sanity_check(int &state) { // fall through case DIPOLAR_P3M: if (dp3m_sanity_checks(node_grid)) - state = 0; + failed = true; break; case DIPOLAR_MDLC_DS: mdlc_sanity_checks(); @@ -86,9 +87,10 @@ void nonbonded_sanity_check(int &state) { } } catch (std::runtime_error const &err) { runtimeErrorMsg() << err.what(); - state = 0; + failed = true; } #endif + return failed; } double cutoff(const Utils::Vector3d &box_l) { diff --git a/src/core/electrostatics_magnetostatics/dipole.hpp b/src/core/electrostatics_magnetostatics/dipole.hpp index bf286d207d5..7ef92038ef3 100644 --- a/src/core/electrostatics_magnetostatics/dipole.hpp +++ b/src/core/electrostatics_magnetostatics/dipole.hpp @@ -70,7 +70,7 @@ extern Dipole_parameters dipole; namespace Dipole { void calc_pressure_long_range(); -void nonbonded_sanity_check(int &state); +bool sanity_checks(); double cutoff(const Utils::Vector3d &box_l); void on_observable_calc(); diff --git a/src/core/electrostatics_magnetostatics/mdlc_correction.cpp b/src/core/electrostatics_magnetostatics/mdlc_correction.cpp index 7e338ca2fa3..bcefe278fdb 100644 --- a/src/core/electrostatics_magnetostatics/mdlc_correction.cpp +++ b/src/core/electrostatics_magnetostatics/mdlc_correction.cpp @@ -78,7 +78,7 @@ double calc_mu_max() { return mu_max; } -REGISTER_CALLBACK_MASTER_RANK(calc_mu_max) +REGISTER_CALLBACK_MAIN_RANK(calc_mu_max) inline double g1_DLC_dip(double g, double x) { auto const c = g / x; @@ -433,7 +433,7 @@ double add_mdlc_energy_corrections(const ParticleRange &particles) { double mdlc_tune_far_cut(DLC_struct const ¶ms) { /* we take the maximum dipole in the system, to be sure that the errors * in the other case will be equal or less than for this one */ - auto const mu_max = mpi_call(Communication::Result::master_rank, calc_mu_max); + auto const mu_max = mpi_call(Communication::Result::main_rank, calc_mu_max); auto const mu_max_sq = mu_max * mu_max; const double n = get_n_part(); diff --git a/src/core/electrostatics_magnetostatics/mmm1d.hpp b/src/core/electrostatics_magnetostatics/mmm1d.hpp index fdfadad2881..f6c90d99570 100644 --- a/src/core/electrostatics_magnetostatics/mmm1d.hpp +++ b/src/core/electrostatics_magnetostatics/mmm1d.hpp @@ -74,7 +74,7 @@ double mmm1d_coulomb_pair_energy(double q1q2, Utils::Vector3d const &d, /** Tuning of the parameters which are not set by the user. Tune either the * @ref MMM1DParameters::far_switch_radius_2 "switching radius" or the * @ref MMM1DParameters::bessel_cutoff "Bessel cutoff". Call this only - * on the master node. + * on the head node. * * @param verbose output information about the tuning (tried values and errors) * @param timings Number of test force calculations diff --git a/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp b/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp index 9671708a294..4060b32cfb3 100644 --- a/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp +++ b/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp @@ -67,9 +67,9 @@ struct dp3m_data_struct : public p3m_data_struct_base { /** k-space mesh (local) for k-space calculation and FFT. */ std::vector ks_mesh; - /** number of dipolar particles (only on master node). */ + /** number of dipolar particles (only on head node). */ int sum_dip_part; - /** Sum of square of magnetic dipoles (only on master node). */ + /** Sum of square of magnetic dipoles (only on head node). */ double sum_mu2; /** position shift for calculation of first assignment mesh point. */ diff --git a/src/core/electrostatics_magnetostatics/p3m.hpp b/src/core/electrostatics_magnetostatics/p3m.hpp index edc967d324e..21fcda2a134 100644 --- a/src/core/electrostatics_magnetostatics/p3m.hpp +++ b/src/core/electrostatics_magnetostatics/p3m.hpp @@ -66,11 +66,11 @@ struct p3m_data_struct : public p3m_data_struct_base { /** mesh (local) for the electric field. */ std::array, 3> E_mesh; - /** number of charged particles (only on master node). */ + /** number of charged particles (only on head node). */ int sum_qpart; - /** Sum of square of charges (only on master node). */ + /** Sum of square of charges (only on head node). */ double sum_q2; - /** square of sum of charges (only on master node). */ + /** square of sum of charges (only on head node). */ double square_sum_q; p3m_interpolation_cache inter_weights; diff --git a/src/core/electrostatics_magnetostatics/scafacos.cpp b/src/core/electrostatics_magnetostatics/scafacos.cpp index 8e90e789164..d8f1fd7aa5a 100644 --- a/src/core/electrostatics_magnetostatics/scafacos.cpp +++ b/src/core/electrostatics_magnetostatics/scafacos.cpp @@ -74,8 +74,8 @@ ScafacosContextBase *fcs_coulomb() { } #ifdef SCAFACOS_DIPOLES -static void set_parameters_dipoles_worker(const std::string &method, - const std::string ¶ms) { +static void set_parameters_dipoles_local(const std::string &method, + const std::string ¶ms) { delete dipoles_instance; dipoles_instance = nullptr; @@ -93,11 +93,11 @@ static void set_parameters_dipoles_worker(const std::string &method, on_coulomb_change(); } -REGISTER_CALLBACK(set_parameters_dipoles_worker) +REGISTER_CALLBACK(set_parameters_dipoles_local) #endif -static void set_parameters_coulomb_worker(const std::string &method, - const std::string ¶ms) { +static void set_parameters_coulomb_local(const std::string &method, + const std::string ¶ms) { delete coulomb_instance; coulomb_instance = nullptr; @@ -116,10 +116,10 @@ static void set_parameters_coulomb_worker(const std::string &method, instance->tune(); } -REGISTER_CALLBACK(set_parameters_coulomb_worker) +REGISTER_CALLBACK(set_parameters_coulomb_local) -void set_r_cut_and_tune_local(double r_cut) { - coulomb_instance->set_r_cut_and_tune_local(r_cut); +void set_r_cut_and_tune(double r_cut) { + coulomb_instance->set_r_cut_and_tune(r_cut); } void free_handle(bool dipolar) { @@ -142,10 +142,10 @@ void set_parameters(const std::string &method, const std::string ¶ms, bool dipolar) { if (dipolar) { #ifdef SCAFACOS_DIPOLES - mpi_call_all(set_parameters_dipoles_worker, method, params); + mpi_call_all(set_parameters_dipoles_local, method, params); #endif } else { - mpi_call_all(set_parameters_coulomb_worker, method, params); + mpi_call_all(set_parameters_coulomb_local, method, params); } } diff --git a/src/core/electrostatics_magnetostatics/scafacos.hpp b/src/core/electrostatics_magnetostatics/scafacos.hpp index 4587623e96c..a4fe21a3e16 100644 --- a/src/core/electrostatics_magnetostatics/scafacos.hpp +++ b/src/core/electrostatics_magnetostatics/scafacos.hpp @@ -52,7 +52,7 @@ void set_parameters(const std::string &method, const std::string ¶ms, bool dipolar); void free_handle(bool dipolar); -void set_r_cut_and_tune_local(double r_cut); +void set_r_cut_and_tune(double r_cut); std::list available_methods(); diff --git a/src/core/energy.cpp b/src/core/energy.cpp index ac2999e0c99..ffce964d177 100644 --- a/src/core/energy.cpp +++ b/src/core/energy.cpp @@ -32,6 +32,7 @@ #include "event.hpp" #include "forces.hpp" #include "integrate.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "short_range_loop.hpp" @@ -47,7 +48,7 @@ static std::shared_ptr calculate_energy_local() { auto obs_energy_ptr = std::make_shared(1); - if (!interactions_sanity_checks()) + if (long_range_interactions_sanity_checks()) return obs_energy_ptr; auto &obs_energy = *obs_energy_ptr; @@ -111,10 +112,10 @@ static std::shared_ptr calculate_energy_local() { return obs_energy_ptr; } -REGISTER_CALLBACK_MASTER_RANK(calculate_energy_local) +REGISTER_CALLBACK_MAIN_RANK(calculate_energy_local) std::shared_ptr calculate_energy() { - return mpi_call(Communication::Result::master_rank, calculate_energy_local); + return mpi_call(Communication::Result::main_rank, calculate_energy_local); } double calculate_current_potential_energy_of_system() { diff --git a/src/core/errorhandling.cpp b/src/core/errorhandling.cpp index be3b0353880..77ca55c23bf 100644 --- a/src/core/errorhandling.cpp +++ b/src/core/errorhandling.cpp @@ -63,11 +63,14 @@ RuntimeErrorStream _runtimeMessageStream(RuntimeError::ErrorLevel level, function); } -void mpi_gather_runtime_errors_slave() { runtimeErrorCollector->gatherSlave(); } -REGISTER_CALLBACK(mpi_gather_runtime_errors_slave) +void mpi_gather_runtime_errors_local() { + runtimeErrorCollector->gather_local(); +} + +REGISTER_CALLBACK(mpi_gather_runtime_errors_local) std::vector mpi_gather_runtime_errors() { - m_callbacks->call(mpi_gather_runtime_errors_slave); + m_callbacks->call(mpi_gather_runtime_errors_local); return runtimeErrorCollector->gather(); } } // namespace ErrorHandling diff --git a/src/core/event.cpp b/src/core/event.cpp index e25d0788d1e..f018a5f48f3 100644 --- a/src/core/event.cpp +++ b/src/core/event.cpp @@ -42,6 +42,7 @@ #include "grid_based_algorithms/lb_interface.hpp" #include "immersed_boundaries.hpp" #include "integrate.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "npt.hpp" #include "partCfg_global.hpp" @@ -108,7 +109,9 @@ void on_integration_start(double time_step) { #ifdef NPT integrator_npt_sanity_checks(); #endif - interactions_sanity_checks(); + if (long_range_interactions_sanity_checks()) { + runtimeErrorMsg() << "Long-range interactions returned an error."; + } lb_lbfluid_sanity_checks(time_step); /********************************************/ diff --git a/src/core/forces.cpp b/src/core/forces.cpp index bbd7dae1e85..f054ba60b7a 100644 --- a/src/core/forces.cpp +++ b/src/core/forces.cpp @@ -41,6 +41,7 @@ #include "grid_based_algorithms/lb_particle_coupling.hpp" #include "immersed_boundaries.hpp" #include "integrate.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/VerletCriterion.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "npt.hpp" @@ -138,13 +139,9 @@ void force_calc(CellStructure &cell_structure, double time_step, double kT) { if (max_oif_objects) { // There are two global quantities that need to be evaluated: - // object's surface and object's volume. One can add another - // quantity. - Utils::Vector2d area_volume; - area_volume[0] = 0.0; - area_volume[1] = 0.0; + // object's surface and object's volume. for (int i = 0; i < max_oif_objects; i++) { - calc_oif_global(area_volume, i, cell_structure); + auto const area_volume = calc_oif_global(i, cell_structure); if (fabs(area_volume[0]) < 1e-100 && fabs(area_volume[1]) < 1e-100) break; add_oif_global_forces(area_volume, i, cell_structure); diff --git a/src/core/grid_based_algorithms/lb_boundaries.cpp b/src/core/grid_based_algorithms/lb_boundaries.cpp index 3dfe139888d..04d4e19c647 100644 --- a/src/core/grid_based_algorithms/lb_boundaries.cpp +++ b/src/core/grid_based_algorithms/lb_boundaries.cpp @@ -259,7 +259,7 @@ void lb_init_boundaries() { } #if defined(LB_BOUNDARIES) -void lb_collect_boundary_forces_local(int, int) { +static void lb_collect_boundary_forces_local() { lb_collect_boundary_forces(nullptr); } @@ -284,7 +284,7 @@ Utils::Vector3d lbboundary_get_force(LBBoundary const *lbb) { #endif } else if (lattice_switch == ActiveLB::CPU) { #if defined(LB_BOUNDARIES) - mpi_call(lb_collect_boundary_forces_local, -1, -1); + mpi_call(lb_collect_boundary_forces_local); lb_collect_boundary_forces(forces.data()); #endif } diff --git a/src/core/grid_based_algorithms/lb_collective_interface.cpp b/src/core/grid_based_algorithms/lb_collective_interface.cpp index a2e1cb8e13c..fade1ffc743 100644 --- a/src/core/grid_based_algorithms/lb_collective_interface.cpp +++ b/src/core/grid_based_algorithms/lb_collective_interface.cpp @@ -163,18 +163,18 @@ auto mpi_lb_get_pressure_tensor(Utils::Vector3i const &index) { REGISTER_CALLBACK_ONE_RANK(mpi_lb_get_pressure_tensor) -void mpi_bcast_lb_params_slave(LBParam field, LB_Parameters const ¶ms) { +void mpi_bcast_lb_params_local(LBParam field, LB_Parameters const ¶ms) { lbpar = params; lb_on_param_change(field); } -REGISTER_CALLBACK(mpi_bcast_lb_params_slave) +REGISTER_CALLBACK(mpi_bcast_lb_params_local) /** @brief Broadcast a parameter for lattice Boltzmann. * @param[in] field References the parameter field to be broadcasted. * The references are defined in lb.hpp */ void mpi_bcast_lb_params(LBParam field) { - mpi_call(mpi_bcast_lb_params_slave, field, lbpar); + mpi_call(mpi_bcast_lb_params_local, field, lbpar); lb_on_param_change(field); } diff --git a/src/core/grid_based_algorithms/lb_interface.cpp b/src/core/grid_based_algorithms/lb_interface.cpp index 8460779437d..f22f79ff524 100644 --- a/src/core/grid_based_algorithms/lb_interface.cpp +++ b/src/core/grid_based_algorithms/lb_interface.cpp @@ -1119,7 +1119,7 @@ const Lattice &lb_lbfluid_get_lattice() { return lblattice; } ActiveLB lb_lbfluid_get_lattice_switch() { return lattice_switch; } -void mpi_lb_lbfluid_calc_fluid_momentum_local(int, int) { +static void mpi_lb_lbfluid_calc_fluid_momentum_local() { lb_calc_fluid_momentum(nullptr, lbpar, lbfields, lblattice); } @@ -1132,7 +1132,7 @@ Utils::Vector3d lb_lbfluid_calc_fluid_momentum() { lb_calc_fluid_momentum_GPU(fluid_momentum.data()); #endif } else if (lattice_switch == ActiveLB::CPU) { - mpi_call(mpi_lb_lbfluid_calc_fluid_momentum_local, -1, -1); + mpi_call(mpi_lb_lbfluid_calc_fluid_momentum_local); lb_calc_fluid_momentum(fluid_momentum.data(), lbpar, lbfields, lblattice); } return fluid_momentum; diff --git a/src/core/grid_based_algorithms/lb_interface.hpp b/src/core/grid_based_algorithms/lb_interface.hpp index a65006ce06a..f146a69b29f 100644 --- a/src/core/grid_based_algorithms/lb_interface.hpp +++ b/src/core/grid_based_algorithms/lb_interface.hpp @@ -256,7 +256,7 @@ Utils::Vector3i lb_lbfluid_get_shape(); Utils::Vector3d lb_lbfluid_calc_fluid_momentum(); /** - * @brief Calculates the interpolated fluid velocity on the master process. + * @brief Calculates the interpolated fluid velocity on the head node process. * @param pos Position at which the velocity is to be calculated. * @retval interpolated fluid velocity. */ @@ -264,7 +264,7 @@ const Utils::Vector3d lb_lbfluid_get_interpolated_velocity(const Utils::Vector3d &pos); /** - * @brief Calculates the interpolated fluid density on the master process. + * @brief Calculates the interpolated fluid density on the head node process. * @param pos Position at which the density is to be calculated. * @retval interpolated fluid density. */ diff --git a/src/core/grid_based_algorithms/lb_particle_coupling.cpp b/src/core/grid_based_algorithms/lb_particle_coupling.cpp index c0517ed81c5..630a756713b 100644 --- a/src/core/grid_based_algorithms/lb_particle_coupling.cpp +++ b/src/core/grid_based_algorithms/lb_particle_coupling.cpp @@ -44,14 +44,14 @@ LB_Particle_Coupling lb_particle_coupling; -void mpi_bcast_lb_particle_coupling_slave() { +void mpi_bcast_lb_particle_coupling_local() { boost::mpi::broadcast(comm_cart, lb_particle_coupling, 0); } -REGISTER_CALLBACK(mpi_bcast_lb_particle_coupling_slave) +REGISTER_CALLBACK(mpi_bcast_lb_particle_coupling_local) void mpi_bcast_lb_particle_coupling() { - mpi_call(mpi_bcast_lb_particle_coupling_slave); + mpi_call(mpi_bcast_lb_particle_coupling_local); boost::mpi::broadcast(comm_cart, lb_particle_coupling, 0); } diff --git a/src/core/immersed_boundary/ImmersedBoundaries.cpp b/src/core/immersed_boundary/ImmersedBoundaries.cpp index fcbda458026..a36b543bf73 100644 --- a/src/core/immersed_boundary/ImmersedBoundaries.cpp +++ b/src/core/immersed_boundary/ImmersedBoundaries.cpp @@ -24,7 +24,6 @@ #include "communication.hpp" #include "grid.hpp" #include "ibm_volcons.hpp" -#include "interactions.hpp" #include "bonded_interactions/bonded_interaction_data.hpp" diff --git a/src/core/immersed_boundary/ibm_volcons.cpp b/src/core/immersed_boundary/ibm_volcons.cpp index 0ed98121e98..745795271e1 100644 --- a/src/core/immersed_boundary/ibm_volcons.cpp +++ b/src/core/immersed_boundary/ibm_volcons.cpp @@ -19,22 +19,8 @@ #include "ibm_volcons.hpp" -#include "communication.hpp" #include "immersed_boundaries.hpp" -#include -#include - -void mpi_set_n_ibm_volcons_bonds_local(int softID) { - immersed_boundaries.register_softID(softID); -} - -REGISTER_CALLBACK(mpi_set_n_ibm_volcons_bonds_local) - -void mpi_set_n_ibm_volcons_bonds(int softID) { - mpi_call_all(mpi_set_n_ibm_volcons_bonds_local, softID); -} - /** Set parameters of volume conservation */ IBMVolCons::IBMVolCons(const int softID, const double kappaV) { this->softID = softID; @@ -44,6 +30,5 @@ IBMVolCons::IBMVolCons(const int softID, const double kappaV) { // this softID. Calculate it later in the init function of // \ref ImmersedBoundaries::init_volume_conservation() volRef = 0.; - if (this_node == 0) - mpi_set_n_ibm_volcons_bonds(softID); + immersed_boundaries.register_softID(softID); } diff --git a/src/core/integrate.cpp b/src/core/integrate.cpp index 5d53a0941a6..011ae63ec9b 100644 --- a/src/core/integrate.cpp +++ b/src/core/integrate.cpp @@ -44,6 +44,7 @@ #include "grid.hpp" #include "grid_based_algorithms/lb_interface.hpp" #include "grid_based_algorithms/lb_particle_coupling.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "npt.hpp" #include "rattle.hpp" @@ -413,14 +414,15 @@ int python_integrate(int n_steps, bool recalc_forces_par, return ES_OK; } -static int mpi_steepest_descent_local(int steps, int) { +static int mpi_steepest_descent_local(int steps) { return integrate(steps, -1); } -REGISTER_CALLBACK_MASTER_RANK(mpi_steepest_descent_local) + +REGISTER_CALLBACK_MAIN_RANK(mpi_steepest_descent_local) int mpi_steepest_descent(int steps) { - return mpi_call(Communication::Result::master_rank, - mpi_steepest_descent_local, steps, 0); + return mpi_call(Communication::Result::main_rank, mpi_steepest_descent_local, + steps); } static int mpi_integrate_local(int n_steps, int reuse_forces) { @@ -519,4 +521,4 @@ REGISTER_CALLBACK(mpi_set_integ_switch_local) void mpi_set_integ_switch(int integ_switch) { mpi_call_all(mpi_set_integ_switch_local, integ_switch); -} \ No newline at end of file +} diff --git a/src/core/integrators/steepest_descent.cpp b/src/core/integrators/steepest_descent.cpp index affb6740207..3c1ebf767e6 100644 --- a/src/core/integrators/steepest_descent.cpp +++ b/src/core/integrators/steepest_descent.cpp @@ -103,15 +103,15 @@ bool steepest_descent_step(const ParticleRange &particles) { return sqrt(f_max_global) < params.f_max; } -void mpi_bcast_steepest_descent_worker() { +void mpi_bcast_steepest_descent_local() { boost::mpi::broadcast(comm_cart, params, 0); } -REGISTER_CALLBACK(mpi_bcast_steepest_descent_worker) +REGISTER_CALLBACK(mpi_bcast_steepest_descent_local) /** Broadcast steepest descent parameters */ void mpi_bcast_steepest_descent() { - mpi_call_all(mpi_bcast_steepest_descent_worker); + mpi_call_all(mpi_bcast_steepest_descent_local); } void steepest_descent_init(const double f_max, const double gamma, diff --git a/src/core/interactions.cpp b/src/core/interactions.cpp index 6750924ebb4..51fa4c887d7 100644 --- a/src/core/interactions.cpp +++ b/src/core/interactions.cpp @@ -23,29 +23,63 @@ #include "TabulatedPotential.hpp" #include "bonded_interactions/bonded_interaction_data.hpp" #include "bonded_interactions/bonded_tab.hpp" -#include "event.hpp" +#include "collision.hpp" +#include "electrostatics_magnetostatics/coulomb.hpp" +#include "electrostatics_magnetostatics/dipole.hpp" +#include "grid.hpp" #include "serialization/IA_parameters.hpp" -#include - #include -#include +#include + +static double recalc_long_range_cutoff() { + auto max_cut_long_range = INACTIVE_CUTOFF; +#ifdef ELECTROSTATICS + max_cut_long_range = + std::max(max_cut_long_range, Coulomb::cutoff(box_geo.length())); +#endif + +#ifdef DIPOLES + max_cut_long_range = + std::max(max_cut_long_range, Dipole::cutoff(box_geo.length())); +#endif + + return max_cut_long_range; +} + +double maximal_cutoff() { + auto max_cut = min_global_cut; + auto const max_cut_long_range = recalc_long_range_cutoff(); + auto const max_cut_bonded = maximal_cutoff_bonded(); + auto const max_cut_nonbonded = maximal_cutoff_nonbonded(); -void mpi_bcast_all_ia_params_local() { - boost::mpi::broadcast(comm_cart, ia_params, 0); + max_cut = std::max(max_cut, max_cut_long_range); + max_cut = std::max(max_cut, max_cut_bonded); + max_cut = std::max(max_cut, max_cut_nonbonded); + max_cut = std::max(max_cut, collision_detection_cutoff()); + + return max_cut; } -REGISTER_CALLBACK(mpi_bcast_all_ia_params_local) +bool long_range_interactions_sanity_checks() { + /* set to zero if initialization was not successful. */ + bool failed = false; + +#ifdef ELECTROSTATICS + failed |= Coulomb::sanity_checks(); +#endif /* ifdef ELECTROSTATICS */ + +#ifdef DIPOLES + failed |= Dipole::sanity_checks(); +#endif /* ifdef DIPOLES */ -void mpi_bcast_all_ia_params() { mpi_call_all(mpi_bcast_all_ia_params_local); } + return failed; +} void mpi_bcast_ia_params_local(int i, int j) { - if (j >= 0) { - // non-bonded interaction parameters - boost::mpi::broadcast(comm_cart, *get_ia_param(i, j), 0); - } + boost::mpi::broadcast(comm_cart, *get_ia_param(i, j), 0); on_short_range_ia_change(); } @@ -54,7 +88,3 @@ REGISTER_CALLBACK(mpi_bcast_ia_params_local) void mpi_bcast_ia_params(int i, int j) { mpi_call_all(mpi_bcast_ia_params_local, i, j); } - -REGISTER_CALLBACK(realloc_ia_params) - -void mpi_realloc_ia_params(int ns) { mpi_call_all(realloc_ia_params, ns); } diff --git a/src/core/interactions.hpp b/src/core/interactions.hpp index 549de87030d..e891b74af97 100644 --- a/src/core/interactions.hpp +++ b/src/core/interactions.hpp @@ -24,8 +24,13 @@ #ifndef _INTERACTIONS_HPP #define _INTERACTIONS_HPP -/** Broadcast \ref ia_params to all nodes. */ -void mpi_bcast_all_ia_params(); +/** Calculate the maximal cutoff of all interactions. */ +double maximal_cutoff(); + +/** Check electrostatic and magnetostatic methods are properly initialized. + * @return true if sanity checks failed. + */ +bool long_range_interactions_sanity_checks(); /** Send new IA params. * Also calls \ref on_short_range_ia_change. @@ -40,9 +45,4 @@ void mpi_bcast_all_ia_params(); */ void mpi_bcast_ia_params(int i, int j); -/** Resize \ref ia_params. - * \param s the new size. - */ -void mpi_realloc_ia_params(int s); - #endif diff --git a/src/core/io/mpiio/mpiio.cpp b/src/core/io/mpiio/mpiio.cpp index 03c4f8eb5f9..35d79e3751c 100644 --- a/src/core/io/mpiio/mpiio.cpp +++ b/src/core/io/mpiio/mpiio.cpp @@ -117,7 +117,7 @@ static void mpiio_dump_array(const std::string &fn, T *arr, std::size_t len, /** Dumps some generic infos like the dumped fields and info to process * the bond information offline (without ESPResSo). To be called by the - * master node only. + * head node only. * * \param fn The filename to write to * \param fields The dumped fields @@ -358,7 +358,7 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { errexit(); } - // 1.head on master node: + // 1.head on head node: // Read head to determine fields at time of writing. // Compare this var to the current fields. unsigned avail_fields; diff --git a/src/core/nonbonded_interactions/nonbonded_interaction_data.cpp b/src/core/nonbonded_interactions/nonbonded_interaction_data.cpp index c3efced4512..4068eccf5f4 100644 --- a/src/core/nonbonded_interactions/nonbonded_interaction_data.cpp +++ b/src/core/nonbonded_interactions/nonbonded_interaction_data.cpp @@ -23,12 +23,10 @@ */ #include "nonbonded_interactions/nonbonded_interaction_data.hpp" -#include "bonded_interactions/bonded_interaction_data.hpp" -#include "collision.hpp" +#include "communication.hpp" #include "electrostatics_magnetostatics/coulomb.hpp" -#include "electrostatics_magnetostatics/dipole.hpp" +#include "event.hpp" #include "grid.hpp" -#include "interactions.hpp" #include "serialization/IA_parameters.hpp" #include @@ -59,6 +57,41 @@ double min_global_cut = INACTIVE_CUTOFF; * general low-level functions *****************************************/ +static void mpi_realloc_ia_params_local(int new_size) { + if (new_size <= max_seen_particle_type) + return; + + auto new_params = std::vector(new_size * (new_size + 1) / 2); + + /* if there is an old field, move entries */ + for (int i = 0; i < max_seen_particle_type; i++) + for (int j = i; j < max_seen_particle_type; j++) { + new_params.at(Utils::upper_triangular(i, j, new_size)) = + std::move(*get_ia_param(i, j)); + } + + max_seen_particle_type = new_size; + std::swap(ia_params, new_params); +} + +REGISTER_CALLBACK(mpi_realloc_ia_params_local) + +/** Increase the size of the @ref ia_params vector. */ +inline void mpi_realloc_ia_params(int new_size) { + mpi_call_all(mpi_realloc_ia_params_local, new_size); +} + +static void mpi_bcast_all_ia_params_local() { + boost::mpi::broadcast(comm_cart, ia_params, 0); +} + +REGISTER_CALLBACK(mpi_bcast_all_ia_params_local) + +/** Broadcast @ref ia_params to all nodes. */ +inline void mpi_bcast_all_ia_params() { + mpi_call_all(mpi_bcast_all_ia_params_local); +} + IA_parameters *get_ia_param_safe(int i, int j) { make_particle_type_exist(std::max(i, j)); return get_ia_param(i, j); @@ -84,21 +117,6 @@ void ia_params_set_state(std::string const &state) { mpi_bcast_all_ia_params(); } -static double recalc_long_range_cutoff() { - auto max_cut_long_range = INACTIVE_CUTOFF; -#ifdef ELECTROSTATICS - max_cut_long_range = - std::max(max_cut_long_range, Coulomb::cutoff(box_geo.length())); -#endif - -#ifdef DIPOLES - max_cut_long_range = - std::max(max_cut_long_range, Dipole::cutoff(box_geo.length())); -#endif - - return max_cut_long_range; -} - static double recalc_maximal_cutoff(const IA_parameters &data) { auto max_cut_current = INACTIVE_CUTOFF; @@ -192,41 +210,6 @@ double maximal_cutoff_nonbonded() { return max_cut_nonbonded; } -double maximal_cutoff() { - auto max_cut = min_global_cut; - auto const max_cut_long_range = recalc_long_range_cutoff(); - auto const max_cut_bonded = maximal_cutoff_bonded(); - auto const max_cut_nonbonded = maximal_cutoff_nonbonded(); - - max_cut = std::max(max_cut, max_cut_long_range); - max_cut = std::max(max_cut, max_cut_bonded); - max_cut = std::max(max_cut, max_cut_nonbonded); - max_cut = std::max(max_cut, collision_detection_cutoff()); - - return max_cut; -} - -/** Increase the LOCAL @ref ia_params field for non-bonded interactions - * to the given size. This function is not exported since it does not - * do this on all nodes. Use @ref make_particle_type_exist for that. - */ -void realloc_ia_params(int nsize) { - if (nsize <= max_seen_particle_type) - return; - - auto new_params = std::vector(nsize * (nsize + 1) / 2); - - /* if there is an old field, move entries */ - for (int i = 0; i < max_seen_particle_type; i++) - for (int j = i; j < max_seen_particle_type; j++) { - new_params.at(Utils::upper_triangular(i, j, nsize)) = - std::move(*get_ia_param(i, j)); - } - - max_seen_particle_type = nsize; - std::swap(ia_params, new_params); -} - void reset_ia_params() { boost::fill(ia_params, IA_parameters{}); mpi_bcast_all_ia_params(); @@ -243,22 +226,7 @@ void make_particle_type_exist(int type) { void make_particle_type_exist_local(int type) { if (is_new_particle_type(type)) - realloc_ia_params(type + 1); -} - -int interactions_sanity_checks() { - /* set to zero if initialization was not successful. */ - int state = 1; - -#ifdef ELECTROSTATICS - Coulomb::sanity_checks(state); -#endif /* ifdef ELECTROSTATICS */ - -#ifdef DIPOLES - Dipole::nonbonded_sanity_check(state); -#endif /* ifdef DIPOLES */ - - return state; + mpi_realloc_ia_params_local(type + 1); } void mpi_set_min_global_cut_local(double min_global_cut) { @@ -270,4 +238,4 @@ REGISTER_CALLBACK(mpi_set_min_global_cut_local) void mpi_set_min_global_cut(double min_global_cut) { mpi_call_all(mpi_set_min_global_cut_local, min_global_cut); -} \ No newline at end of file +} diff --git a/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp b/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp index 9bb9deed528..0bc9b9c9300 100644 --- a/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp +++ b/src/core/nonbonded_interactions/nonbonded_interaction_data.hpp @@ -287,9 +287,6 @@ extern int max_seen_particle_type; * interactions). */ double maximal_cutoff_nonbonded(); -/** Maximal interaction cutoff (bonded interactions). - */ -double maximal_cutoff_bonded(); /** Minimal global interaction cutoff. Particles with a distance * smaller than this are guaranteed to be available on the same node @@ -339,24 +336,11 @@ void make_particle_type_exist(int type); void make_particle_type_exist_local(int type); -/** This function increases the LOCAL ia_params field to the given size. - * Better use \ref make_particle_type_exist since it takes care of - * the other nodes. - */ -void realloc_ia_params(int nsize); - -/** Calculate the maximal cutoff of all pair interactions. - */ -double maximal_cutoff(); - /** * @brief Reset all interaction parameters to their defaults. */ void reset_ia_params(); -/** Check whether all force calculation routines are properly initialized. */ -int interactions_sanity_checks(); - /** Check if a non-bonded interaction is defined */ inline bool checkIfInteraction(IA_parameters const &data) { return data.max_cut != INACTIVE_CUTOFF; diff --git a/src/core/npt.cpp b/src/core/npt.cpp index 1a0d6a1b786..fbcc3930c2c 100644 --- a/src/core/npt.cpp +++ b/src/core/npt.cpp @@ -56,7 +56,7 @@ void synchronize_npt_state() { boost::mpi::broadcast(comm_cart, nptiso.volume, 0); } -void mpi_bcast_nptiso_geom_barostat_worker() { +void mpi_bcast_nptiso_geom_barostat_local() { boost::mpi::broadcast(comm_cart, nptiso.geometry, 0); boost::mpi::broadcast(comm_cart, nptiso.dimension, 0); boost::mpi::broadcast(comm_cart, nptiso.cubic_box, 0); @@ -66,11 +66,11 @@ void mpi_bcast_nptiso_geom_barostat_worker() { on_thermostat_param_change(); } -REGISTER_CALLBACK(mpi_bcast_nptiso_geom_barostat_worker) +REGISTER_CALLBACK(mpi_bcast_nptiso_geom_barostat_local) /** Broadcast nptiso geometry and barostat parameters to all nodes. */ void mpi_bcast_nptiso_geom_barostat() { - mpi_call_all(mpi_bcast_nptiso_geom_barostat_worker); + mpi_call_all(mpi_bcast_nptiso_geom_barostat_local); } void integrator_npt_coulomb_dipole_sanity_checks( diff --git a/src/core/object-in-fluid/oif_global_forces.cpp b/src/core/object-in-fluid/oif_global_forces.cpp index eb4d5ce672f..bd7cd4c5d88 100644 --- a/src/core/object-in-fluid/oif_global_forces.cpp +++ b/src/core/object-in-fluid/oif_global_forces.cpp @@ -20,10 +20,10 @@ #include "oif_global_forces.hpp" #include "BoxGeometry.hpp" +#include "CellStructure.hpp" #include "Particle.hpp" #include "communication.hpp" #include "grid.hpp" -#include "interactions.hpp" #include "bonded_interactions/bonded_interaction_data.hpp" @@ -32,21 +32,19 @@ #include #include -#include +#include + +#include -using Utils::angle_btw_triangles; using Utils::area_triangle; using Utils::get_n_triangle; -void calc_oif_global(Utils::Vector2d &area_volume, int molType, - CellStructure &cs) { +Utils::Vector2d calc_oif_global(int molType, CellStructure &cs) { // first-fold-then-the-same approach double partArea = 0.0; // z volume double VOL_partVol = 0.; - Utils::Vector2d part_area_volume; // added - cs.bond_loop([&partArea, &VOL_partVol, molType](Particle &p1, int bond_id, Utils::Span partners) { @@ -73,11 +71,8 @@ void calc_oif_global(Utils::Vector2d &area_volume, int molType, return false; }); - part_area_volume[0] = partArea; - part_area_volume[1] = VOL_partVol; - - MPI_Allreduce(part_area_volume.data(), area_volume.data(), 2, MPI_DOUBLE, - MPI_SUM, MPI_COMM_WORLD); + auto const area_volume_local = Utils::Vector2d{{partArea, VOL_partVol}}; + return boost::mpi::all_reduce(comm_cart, area_volume_local, std::plus<>()); } void add_oif_global_forces(Utils::Vector2d const &area_volume, int molType, diff --git a/src/core/object-in-fluid/oif_global_forces.hpp b/src/core/object-in-fluid/oif_global_forces.hpp index 5b78d4b5d85..aa8a9dea2f5 100644 --- a/src/core/object-in-fluid/oif_global_forces.hpp +++ b/src/core/object-in-fluid/oif_global_forces.hpp @@ -32,12 +32,10 @@ * Called in force_calc() from within forces.cpp * - calculates the global area and global volume for a cell before the forces * are handled - * - sums up parts for area with mpi_reduce from local triangles - * - synchronization with allreduce + * - MPI synchronization with all reduce * - !!! loop over particles from domain_decomposition !!! */ -void calc_oif_global(Utils::Vector2d &area_volume, int molType, - CellStructure &cs); +Utils::Vector2d calc_oif_global(int molType, CellStructure &cs); /** Distribute the OIF global forces to all particles in the mesh. */ void add_oif_global_forces(Utils::Vector2d const &area_volume, int molType, diff --git a/src/core/pair_criteria/pair_criteria.hpp b/src/core/pair_criteria/pair_criteria.hpp index 991b0712795..ac4d787c693 100644 --- a/src/core/pair_criteria/pair_criteria.hpp +++ b/src/core/pair_criteria/pair_criteria.hpp @@ -31,8 +31,10 @@ class PairCriterion { public: /** @brief Make a decision based on two Particle objects */ virtual bool decide(const Particle &p1, const Particle &p2) const = 0; - /** @brief Make a decision based on particle ids. - * This can only run on the master node outside the integration loop */ + /** + * @brief Make a decision based on particle ids. + * This can only run on the head node outside the integration loop. + */ bool decide(int id1, int id2) const { // Retrieve particle data auto const &p1 = get_particle_data(id1); diff --git a/src/core/particle_data.cpp b/src/core/particle_data.cpp index e085167fd45..bdf049d0cb6 100644 --- a/src/core/particle_data.cpp +++ b/src/core/particle_data.cpp @@ -401,7 +401,7 @@ void add_exclusion(Particle *part, int part2); void auto_exclusion(int distance); -void mpi_who_has_local(int, int) { +static void mpi_who_has_local() { static std::vector sendbuf; auto local_particles = cell_structure.local_particles(); @@ -423,7 +423,7 @@ void mpi_who_has_local(int, int) { REGISTER_CALLBACK(mpi_who_has_local) void mpi_who_has() { - mpi_call(mpi_who_has_local, -1, 0); + mpi_call(mpi_who_has_local); auto local_particles = cell_structure.local_particles(); @@ -519,7 +519,7 @@ const Particle &get_particle_data(int part) { return *cache_ptr; } -void mpi_get_particles_local(int, int) { +static void mpi_get_particles_local() { std::vector ids; boost::mpi::scatter(comm_cart, ids, 0); @@ -544,7 +544,7 @@ REGISTER_CALLBACK(mpi_get_particles_local) * @returns The particle list. */ std::vector mpi_get_particles(Utils::Span ids) { - mpi_call(mpi_get_particles_local, 0, 0); + mpi_call(mpi_get_particles_local); /* Return value */ std::vector parts(ids.size()); @@ -938,9 +938,9 @@ const std::vector &get_particle_bonds(int part) { return ret; } -void mpi_remove_particle_local(int, int part) { - if (part != -1) { - cell_structure.remove_particle(part); +static void mpi_remove_particle_local(int p_id) { + if (p_id != -1) { + cell_structure.remove_particle(p_id); } else { cell_structure.remove_all_particles(); } @@ -953,12 +953,12 @@ REGISTER_CALLBACK(mpi_remove_particle_local) * Also calls \ref on_particle_change. * \param p_id the particle to remove, use -1 to remove all particles. */ -void mpi_remove_particle(int, int p_id) { - mpi_call_all(mpi_remove_particle_local, -1, p_id); +void mpi_remove_particle(int p_id) { + mpi_call_all(mpi_remove_particle_local, p_id); } void remove_all_particles() { - mpi_remove_particle(-1, -1); + mpi_remove_particle(-1); clear_particle_node(); } @@ -971,8 +971,7 @@ int remove_particle(int p_id) { } particle_node[p_id] = -1; - mpi_remove_particle(-1, p_id); - + mpi_remove_particle(p_id); particle_node.erase(p_id); return ES_OK; @@ -992,7 +991,7 @@ void local_rescale_particles(int dir, double scale) { } } -void mpi_rescale_particles_local(int, int dir) { +static void mpi_rescale_particles_local(int dir) { double scale = 0.0; MPI_Recv(&scale, 1, MPI_DOUBLE, 0, SOME_TAG, comm_cart, MPI_STATUS_IGNORE); local_rescale_particles(dir, scale); @@ -1002,7 +1001,7 @@ void mpi_rescale_particles_local(int, int dir) { REGISTER_CALLBACK(mpi_rescale_particles_local) void mpi_rescale_particles(int dir, double scale) { - mpi_call(mpi_rescale_particles_local, -1, dir); + mpi_call(mpi_rescale_particles_local, dir); for (int pnode = 0; pnode < n_nodes; pnode++) { if (pnode == this_node) { local_rescale_particles(dir, scale); diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index 7e8681f4a4d..bc078c3a60a 100644 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -99,7 +99,7 @@ void invalidate_fetch_cache(); */ std::size_t fetch_cache_max_size(); -/** Call only on the master node. +/** Call only on the head node. * Move a particle to a new position. * If it does not exist, it is created. * @param part the identity of the particle to move @@ -110,41 +110,41 @@ std::size_t fetch_cache_max_size(); */ int place_particle(int part, Utils::Vector3d const &p); -/** Call only on the master node: set particle velocity. +/** Call only on the head node: set particle velocity. * @param part the particle. * @param v its new velocity. */ void set_particle_v(int part, Utils::Vector3d const &v); #ifdef ENGINE -/** Call only on the master node: set particle velocity. +/** Call only on the head node: set particle velocity. * @param part the particle. * @param swim struct containing swimming parameters */ void set_particle_swimming(int part, ParticleParametersSwimming swim); #endif -/** Call only on the master node: set particle force. +/** Call only on the head node: set particle force. * @param part the particle. * @param F its new force. */ void set_particle_f(int part, const Utils::Vector3d &F); -/** Call only on the master node: set particle mass. +/** Call only on the head node: set particle mass. * @param part the particle. * @param mass its new mass. */ void set_particle_mass(int part, double mass); #ifdef ROTATIONAL_INERTIA -/** Call only on the master node: set particle rotational inertia. +/** Call only on the head node: set particle rotational inertia. * @param part the particle. * @param rinertia its new inertia. */ void set_particle_rotational_inertia(int part, Utils::Vector3d const &rinertia); #endif -/** Call only on the master node: Specifies whether a particle's rotational +/** Call only on the head node: Specifies whether a particle's rotational * degrees of freedom are integrated or not. If set to zero, the content of * the torque and omega variables are meaningless * @param part the particle. @@ -160,59 +160,59 @@ void set_particle_rotation(int part, int rot); */ void rotate_particle(int part, const Utils::Vector3d &axis, double angle); -/** Call only on the master node: set particle charge. +/** Call only on the head node: set particle charge. * @param part the particle. * @param q its new charge. */ void set_particle_q(int part, double q); #ifdef LB_ELECTROHYDRODYNAMICS -/** Call only on the master node: set particle electrophoretic mobility. +/** Call only on the head node: set particle electrophoretic mobility. * @param part the particle. * @param mu_E its new mobility. */ void set_particle_mu_E(int part, Utils::Vector3d const &mu_E); #endif -/** Call only on the master node: set particle type. +/** Call only on the head node: set particle type. * @param p_id the particle. * @param type its new type. */ void set_particle_type(int p_id, int type); -/** Call only on the master node: set particle's molecule id. +/** Call only on the head node: set particle's molecule id. * @param part the particle. * @param mid its new mol id. */ void set_particle_mol_id(int part, int mid); #ifdef ROTATION -/** Call only on the master node: set particle orientation using quaternions. +/** Call only on the head node: set particle orientation using quaternions. * @param part the particle. * @param quat its new value for quaternions. */ void set_particle_quat(int part, Utils::Quaternion const &quat); -/** Call only on the master node: set particle orientation using director. +/** Call only on the head node: set particle orientation using director. * The particle director defines the z-axis in the body-fixed frame. * @param part the particle. * @param director its new director vector (will be normalized if necessary) */ void set_particle_director(int part, const Utils::Vector3d &director); -/** Call only on the master node: set particle angular velocity from lab frame. +/** Call only on the head node: set particle angular velocity from lab frame. * @param part the particle. * @param omega_lab its new angular velocity. */ void set_particle_omega_lab(int part, const Utils::Vector3d &omega_lab); -/** Call only on the master node: set particle angular velocity in body frame. +/** Call only on the head node: set particle angular velocity in body frame. * @param part the particle. * @param omega its new angular velocity. */ void set_particle_omega_body(int part, const Utils::Vector3d &omega); -/** Call only on the master node: set particle torque from lab frame. +/** Call only on the head node: set particle torque from lab frame. * @param part the particle. * @param torque_lab its new torque. */ @@ -220,13 +220,13 @@ void set_particle_torque_lab(int part, const Utils::Vector3d &torque_lab); #endif #ifdef DIPOLES -/** Call only on the master node: set particle dipole orientation. +/** Call only on the head node: set particle dipole orientation. * @param part the particle. * @param dip its new dipole orientation. */ void set_particle_dip(int part, Utils::Vector3d const &dip); -/** Call only on the master node: set particle dipole moment (absolute value). +/** Call only on the head node: set particle dipole moment (absolute value). * @param part the particle. * @param dipm its new dipole moment. */ @@ -234,7 +234,7 @@ void set_particle_dipm(int part, double dipm); #endif #ifdef VIRTUAL_SITES -/** Call only on the master node: set particle virtual flag. +/** Call only on the head node: set particle virtual flag. * @param part the particle. * @param is_virtual new @ref ParticleProperties::is_virtual "is_virtual" flag. */ @@ -248,7 +248,7 @@ void set_particle_vs_relative(int part, int vs_relative_to, double vs_distance, #endif #ifdef THERMOSTAT_PER_PARTICLE -/** Call only on the master node: set particle frictional coefficient. +/** Call only on the head node: set particle frictional coefficient. * @param part the particle. * @param gamma its new frictional coefficient. */ @@ -268,18 +268,18 @@ void set_particle_gamma_rot(int part, Utils::Vector3d const &gamma_rot); #ifdef EXTERNAL_FORCES #ifdef ROTATION -/** Call only on the master node: set particle external torque. +/** Call only on the head node: set particle external torque. * @param part the particle. * @param torque new value for ext_torque. */ void set_particle_ext_torque(int part, const Utils::Vector3d &torque); #endif -/** Call only on the master node: set particle external force. +/** Call only on the head node: set particle external force. * @param part the particle. * @param force new value for ext_force. */ void set_particle_ext_force(int part, const Utils::Vector3d &force); -/** Call only on the master node: set coordinate axes for which the particles +/** Call only on the head node: set coordinate axes for which the particles * motion is fixed. * @param part the particle. * @param flag new value for flagged coordinate axes to be fixed @@ -287,19 +287,19 @@ void set_particle_ext_force(int part, const Utils::Vector3d &force); void set_particle_fix(int part, uint8_t flag); #endif -/** Call only on the master node: remove bond from particle. +/** Call only on the head node: remove bond from particle. * @param part identity of principal atom of the bond. * @param bond field containing the bond type number and the identity * of all bond partners (secondary atoms of the bond). */ void delete_particle_bond(int part, Utils::Span bond); -/** Call only on the master node: remove all bonds from particle. +/** Call only on the head node: remove all bonds from particle. * @param part identity of principal atom of the bond. */ void delete_particle_bonds(int part); -/** Call only on the master node: Add bond to particle. +/** Call only on the head node: Add bond to particle. * @param part identity of principal atom of the bond. * @param bond field containing the bond type number and the * identity of all bond partners (secondary atoms of the bond). @@ -309,7 +309,7 @@ void add_particle_bond(int part, Utils::Span bond); const std::vector &get_particle_bonds(int part); #ifdef EXCLUSIONS -/** Call only on the master node: change particle constraints. +/** Call only on the head node: change particle constraints. * @param part identity of particle for which the exclusion is set. * @param part2 identity of particle for which the exclusion is set. * If -1, delete all exclusions. diff --git a/src/core/pressure.cpp b/src/core/pressure.cpp index 45bf7ea99a6..b214e093004 100644 --- a/src/core/pressure.cpp +++ b/src/core/pressure.cpp @@ -32,6 +32,7 @@ #include "config.hpp" #include "event.hpp" #include "grid.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "pressure_inline.hpp" #include "virtual_sites.hpp" @@ -56,7 +57,7 @@ static std::shared_ptr calculate_pressure_local() { auto obs_pressure_ptr = std::make_shared(9); - if (!interactions_sanity_checks()) + if (long_range_interactions_sanity_checks()) return obs_pressure_ptr; auto &obs_pressure = *obs_pressure_ptr; @@ -117,10 +118,10 @@ static std::shared_ptr calculate_pressure_local() { return obs_pressure_ptr; } -REGISTER_CALLBACK_MASTER_RANK(calculate_pressure_local) +REGISTER_CALLBACK_MAIN_RANK(calculate_pressure_local) std::shared_ptr calculate_pressure() { - return mpi_call(Communication::Result::master_rank, calculate_pressure_local); + return mpi_call(Communication::Result::main_rank, calculate_pressure_local); } Utils::Vector9d observable_compute_pressure_tensor() { diff --git a/src/core/rotate_system.cpp b/src/core/rotate_system.cpp index d5f4c858f2f..f55dd95deb9 100644 --- a/src/core/rotate_system.cpp +++ b/src/core/rotate_system.cpp @@ -34,10 +34,9 @@ #include #include -namespace mpi = boost::mpi; +static void mpi_rotate_system_local(double phi, double theta, double alpha) { + auto const particles = cell_structure.local_particles(); -void local_rotate_system(double phi, double theta, double alpha, - const ParticleRange &particles) { // Calculate center of mass Utils::Vector3d local_com{}; double local_mass = 0.0; @@ -49,9 +48,10 @@ void local_rotate_system(double phi, double theta, double alpha, } } - auto const total_mass = mpi::all_reduce(comm_cart, local_mass, std::plus<>()); + auto const total_mass = + boost::mpi::all_reduce(comm_cart, local_mass, std::plus<>()); auto const com = - mpi::all_reduce(comm_cart, local_com, std::plus<>()) / total_mass; + boost::mpi::all_reduce(comm_cart, local_com, std::plus<>()) / total_mass; // Rotation axis in Cartesian coordinates Utils::Vector3d axis; @@ -62,11 +62,7 @@ void local_rotate_system(double phi, double theta, double alpha, // Rotate particle coordinates for (auto &p : particles) { // Move the center of mass of the system to the origin - for (int j = 0; j < 3; j++) { - p.r.p[j] -= com[j]; - } - - p.r.p = com + Utils::vec_rotate(axis, alpha, p.r.p); + p.r.p = com + Utils::vec_rotate(axis, alpha, p.r.p - com); #ifdef ROTATION local_rotate_particle(p, axis, alpha); #endif @@ -77,28 +73,8 @@ void local_rotate_system(double phi, double theta, double alpha, update_dependent_particles(); } -void mpi_rotate_system_local(int, int) { - std::array params; - mpi::broadcast(comm_cart, params, 0); - - local_rotate_system(params[0], params[1], params[2], - cell_structure.local_particles()); -} - REGISTER_CALLBACK(mpi_rotate_system_local) void mpi_rotate_system(double phi, double theta, double alpha) { - mpi_call(mpi_rotate_system_local, 0, 0); - - std::array params{{phi, theta, alpha}}; - mpi::broadcast(comm_cart, params, 0); - - local_rotate_system(params[0], params[1], params[2], - cell_structure.local_particles()); -} - -/** Rotate all particle coordinates around an axis given by phi,theta through - * the center of mass by an angle alpha */ -void rotate_system(double phi, double theta, double alpha) { - mpi_rotate_system(phi, theta, alpha); + mpi_call_all(mpi_rotate_system_local, phi, theta, alpha); } diff --git a/src/core/rotate_system.hpp b/src/core/rotate_system.hpp index 5144af553b7..d1eaee10175 100644 --- a/src/core/rotate_system.hpp +++ b/src/core/rotate_system.hpp @@ -22,6 +22,6 @@ /** Rotate all particle coordinates around an axis given by phi,theta through * the center of mass by an angle alpha */ -void rotate_system(double phi, double theta, double alpha); +void mpi_rotate_system(double phi, double theta, double alpha); #endif diff --git a/src/core/statistics.cpp b/src/core/statistics.cpp index fc40a61a15c..5ad04741ed5 100644 --- a/src/core/statistics.cpp +++ b/src/core/statistics.cpp @@ -77,7 +77,7 @@ double mindist(PartCfg &partCfg, const std::vector &set1, return std::sqrt(mindist2); } -Utils::Vector3d local_particle_momentum() { +static Utils::Vector3d mpi_particle_momentum_local() { auto const particles = cell_structure.local_particles(); auto const momentum = std::accumulate(particles.begin(), particles.end(), Utils::Vector3d{}, @@ -88,7 +88,7 @@ Utils::Vector3d local_particle_momentum() { return momentum; } -REGISTER_CALLBACK_REDUCTION(local_particle_momentum, +REGISTER_CALLBACK_REDUCTION(mpi_particle_momentum_local, std::plus()) Utils::Vector3d calc_linear_momentum(int include_particles, @@ -97,7 +97,7 @@ Utils::Vector3d calc_linear_momentum(int include_particles, if (include_particles) { linear_momentum += mpi_call(::Communication::Result::reduction, - std::plus(), local_particle_momentum); + std::plus(), mpi_particle_momentum_local); } if (include_lbfluid) { linear_momentum += lb_lbfluid_calc_fluid_momentum(); diff --git a/src/core/stokesian_dynamics/sd_interface.cpp b/src/core/stokesian_dynamics/sd_interface.cpp index 86c4bcdfa1c..e41c1045619 100644 --- a/src/core/stokesian_dynamics/sd_interface.cpp +++ b/src/core/stokesian_dynamics/sd_interface.cpp @@ -86,9 +86,9 @@ BOOST_IS_BITWISE_SERIALIZABLE(SD_particle_data) void sd_update_locally(ParticleRange const &parts) { std::size_t i = 0; - // Even though on the master node, the v_sd vector is larger than + // Even though on the head node, the v_sd vector is larger than // the (local) parts vector, this should still work. Because the local - // particles correspond to the first 6*n entries in the master's v_sd + // particles correspond to the first 6*n entries in the head node's v_sd // (which holds the velocities of ALL particles). for (auto &p : parts) { @@ -154,8 +154,8 @@ void propagate_vel_pos_sd(const ParticleRange &particles, [](auto const &p) { return SD_particle_data(p); }); Utils::Mpi::gather_buffer(parts_buffer, comm, 0); - /* Buffer that holds local particle data, and all particles on the master - * node used for sending particle data to master node. */ + /* Buffer that holds local particle data, and all particles on the head + * node used for sending particle data to head node. */ if (comm.rank() == 0) { std::size_t n_part = parts_buffer.size(); diff --git a/src/core/tuning.cpp b/src/core/tuning.cpp index 4e3389b8c07..1a332acd270 100644 --- a/src/core/tuning.cpp +++ b/src/core/tuning.cpp @@ -27,6 +27,7 @@ #include "errorhandling.hpp" #include "grid.hpp" #include "integrate.hpp" +#include "interactions.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include diff --git a/src/core/unit_tests/MpiCallbacks_test.cpp b/src/core/unit_tests/MpiCallbacks_test.cpp index 7542daf795b..1d214d7d5a3 100644 --- a/src/core/unit_tests/MpiCallbacks_test.cpp +++ b/src/core/unit_tests/MpiCallbacks_test.cpp @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(invoke_test) { /* * Test that the implementation of callback_model_t - * correctly deserialize the parameters and call + * correctly deserializes the parameters and calls * the callback with them. */ BOOST_AUTO_TEST_CASE(callback_model_t) { @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(callback_model_t) { BOOST_CHECK(called); } - /* Lambda */ + /* lambda */ { called = false; auto cb = detail::make_model([state = 19](int i, double d) { @@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(one_rank_callback) { } } -BOOST_AUTO_TEST_CASE(master_rank_callback) { +BOOST_AUTO_TEST_CASE(main_rank_callback) { auto cb = []() -> int { boost::mpi::communicator world; if (world.rank() == 0) { @@ -250,14 +250,13 @@ BOOST_AUTO_TEST_CASE(master_rank_callback) { auto const fp = static_cast(cb); - Communication::MpiCallbacks::add_static(Communication::Result::master_rank, - fp); + Communication::MpiCallbacks::add_static(Communication::Result::main_rank, fp); boost::mpi::communicator world; Communication::MpiCallbacks cbs(world); if (0 == world.rank()) { - BOOST_CHECK_EQUAL(cbs.call(Communication::Result::master_rank, fp), + BOOST_CHECK_EQUAL(cbs.call(Communication::Result::main_rank, fp), world.size()); } else { cbs.loop(); @@ -284,6 +283,27 @@ BOOST_AUTO_TEST_CASE(call_all) { BOOST_CHECK(called); } +BOOST_AUTO_TEST_CASE(check_exceptions) { + auto cb1 = []() {}; + auto cb2 = []() {}; + + auto const fp1 = static_cast(cb1); + auto const fp2 = static_cast(cb2); + + Communication::MpiCallbacks::add_static(fp1); + + boost::mpi::communicator world; + Communication::MpiCallbacks cbs(world); + + if (0 == world.rank()) { + // can't call an unregistered callback + BOOST_CHECK_THROW(cbs.call(fp2), std::out_of_range); + } else { + // can't call a callback from worker nodes + BOOST_CHECK_THROW(cbs.call(fp1), std::logic_error); + } +} + int main(int argc, char **argv) { boost::mpi::environment mpi_env(argc, argv); diff --git a/src/core/unit_tests/RuntimeErrorCollector_test.cpp b/src/core/unit_tests/RuntimeErrorCollector_test.cpp index 08a6126ff08..9ed3f527f79 100644 --- a/src/core/unit_tests/RuntimeErrorCollector_test.cpp +++ b/src/core/unit_tests/RuntimeErrorCollector_test.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(count) { /* * Check the message gathering. Every node generates a runtime error * and a warning. Then we gather the messages - * on the master and check if we got the correct messages. Then we + * on the head node and check if we got the correct messages. Then we * check the post-condition count() == 0. */ BOOST_AUTO_TEST_CASE(gather) { @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(gather) { return e.level() == RuntimeError::ErrorLevel::ERROR; }) == world.size()); } else { - rec.gatherSlave(); + rec.gather_local(); } Testing::reduce_and_check(world, rec.count() == 0); diff --git a/src/core/virtual_sites/lb_inertialess_tracers_cuda_interface.cpp b/src/core/virtual_sites/lb_inertialess_tracers_cuda_interface.cpp index 1501fe3ac1e..b575e61eeef 100644 --- a/src/core/virtual_sites/lb_inertialess_tracers_cuda_interface.cpp +++ b/src/core/virtual_sites/lb_inertialess_tracers_cuda_interface.cpp @@ -62,7 +62,7 @@ static void pack_particles(ParticleRange const &particles, } } -/** Gather particle positions on the master node in order to communicate them +/** Gather particle positions on the head node in order to communicate them * to GPU. We transfer all particles (real and virtual), but actually we would * only need the virtual ones. Room for improvement... * Analogous to @ref cuda_mpi_get_particles. @@ -112,7 +112,7 @@ void IBM_cuda_mpi_send_velocities(ParticleRange const &particles) { set_velocities(particles, buffer); } else { - /* Scatter forces to slaves */ + /* Scatter forces */ Utils::Mpi::scatter_buffer(IBM_ParticleDataOutput_host.data(), n_part, comm_cart); diff --git a/src/python/espressomd/__init__.py b/src/python/espressomd/__init__.py index 20f4ec94dbf..5d40d83a2b7 100644 --- a/src/python/espressomd/__init__.py +++ b/src/python/espressomd/__init__.py @@ -19,7 +19,7 @@ # # Define the espressomd package -# Initialize MPI, start the main loop on the slaves +# Initialize MPI, start the main loop on the worker nodes from . import _init from .system import System diff --git a/src/python/espressomd/_init.pyx b/src/python/espressomd/_init.pyx index af2673c5be1..53416b433d0 100644 --- a/src/python/espressomd/_init.pyx +++ b/src/python/espressomd/_init.pyx @@ -30,8 +30,8 @@ communication.init(mpi_env) # Has to be _after_ mpi_init script_interface.init(communication.mpiCallbacks()) -# Block the slaves in the callback loop -# The master is just returning to the user script +# Block the worker nodes in the callback loop. +# The head node is just returning to the user script. if communication.this_node != 0: communication.mpi_loop() sys.exit(0) diff --git a/src/python/espressomd/cellsystem.pxd b/src/python/espressomd/cellsystem.pxd index 06b0dc9db4d..ecf56f006c8 100644 --- a/src/python/espressomd/cellsystem.pxd +++ b/src/python/espressomd/cellsystem.pxd @@ -70,6 +70,8 @@ cdef extern from "DomainDecomposition.hpp": cdef extern from "grid.hpp": void mpi_set_node_grid(const Vector3i & node_grid) -cdef extern from "nonbonded_interactions/nonbonded_interaction_data.hpp": +cdef extern from "bonded_interactions/bonded_interaction_data.hpp": double maximal_cutoff_bonded() + +cdef extern from "nonbonded_interactions/nonbonded_interaction_data.hpp": double maximal_cutoff_nonbonded() diff --git a/src/python/espressomd/interactions.pyx b/src/python/espressomd/interactions.pyx index cc3ffec2c26..cfec6030c31 100644 --- a/src/python/espressomd/interactions.pyx +++ b/src/python/espressomd/interactions.pyx @@ -2919,9 +2919,6 @@ class BondedInteractions(ScriptObjectRegistry): """ self.call_method("clear") - def __getitem__(self, bond_id): - return self._get_bond(bond_id) - def _get_bond(self, bond_id): if not is_valid_type(bond_id, int): raise ValueError( @@ -2942,9 +2939,15 @@ class BondedInteractions(ScriptObjectRegistry): # which links to the bonded interaction object return bond_class(bond_id) + def __getitem__(self, bond_id): + return self._get_bond(bond_id) + def __setitem__(self, bond_id, value): self._insert_bond(value, bond_id) + def __delitem__(self, bond_id): + self.remove(bond_id) + def _insert_bond(self, bond, bond_id=None): """ Inserts a new bond. If a ``bond_id`` is given, the bond is inserted at diff --git a/src/python/espressomd/system.pxd b/src/python/espressomd/system.pxd index 5b590b97bd7..b02f9410ed6 100644 --- a/src/python/espressomd/system.pxd +++ b/src/python/espressomd/system.pxd @@ -27,7 +27,7 @@ cdef extern from "grid.hpp": void rescale_boxl(int dir, double d_new) cdef extern from "rotate_system.hpp": - void rotate_system(double phi, double theta, double alpha) + void mpi_rotate_system(double phi, double theta, double alpha) IF EXCLUSIONS: cdef extern from "particle_data.hpp": diff --git a/src/python/espressomd/system.pyx b/src/python/espressomd/system.pyx index 76d02fc92da..995debf502d 100644 --- a/src/python/espressomd/system.pyx +++ b/src/python/espressomd/system.pyx @@ -427,7 +427,7 @@ cdef class System: How much to rotate """ - rotate_system(kwargs['phi'], kwargs['theta'], kwargs['alpha']) + mpi_rotate_system(kwargs['phi'], kwargs['theta'], kwargs['alpha']) IF EXCLUSIONS: def auto_exclusions(self, distance): diff --git a/src/script_interface/interactions/BondedInteractions.hpp b/src/script_interface/interactions/BondedInteractions.hpp index 34c942e3739..5d71f26cc3f 100644 --- a/src/script_interface/interactions/BondedInteractions.hpp +++ b/src/script_interface/interactions/BondedInteractions.hpp @@ -42,14 +42,18 @@ class BondedInteractions : public ObjectMap { using mapped_type = typename container_type::mapped_type; key_type insert_in_core(mapped_type const &obj_ptr) override { - return ::bonded_ia_params.insert(obj_ptr->bonded_ia()); + auto const key = ::bonded_ia_params.insert(obj_ptr->bonded_ia()); + mpi_update_cell_system_ia_range_local(); + return key; } void insert_in_core(key_type const &key, mapped_type const &obj_ptr) override { ::bonded_ia_params.insert(key, obj_ptr->bonded_ia()); + mpi_update_cell_system_ia_range_local(); } void erase_in_core(key_type const &key) override { ::bonded_ia_params.erase(key); + mpi_update_cell_system_ia_range_local(); } Variant do_call_method(std::string const &name, diff --git a/src/utils/include/utils/mpi/gather_buffer.hpp b/src/utils/include/utils/mpi/gather_buffer.hpp index 61e501856f7..d3cb75268dd 100644 --- a/src/utils/include/utils/mpi/gather_buffer.hpp +++ b/src/utils/include/utils/mpi/gather_buffer.hpp @@ -45,8 +45,8 @@ namespace Mpi { * This encapsulates a common combination of MPI_Gather() * and MPI_{Send,Recv}(). * - * @param buffer On the master the target buffer that has the local - * part in the beginning. On the slaves the local buffer. + * @param buffer On the head node: the target buffer that has the local + * part in the beginning. On worker nodes: the local buffer. * @param comm The MPI communicator. * @param root The rank where the data should be gathered. */ diff --git a/src/utils/include/utils/mpi/scatter_buffer.hpp b/src/utils/include/utils/mpi/scatter_buffer.hpp index 4063265f865..25a4c32b59b 100644 --- a/src/utils/include/utils/mpi/scatter_buffer.hpp +++ b/src/utils/include/utils/mpi/scatter_buffer.hpp @@ -36,7 +36,7 @@ namespace Mpi { * @brief Scatter buffer with different size on each node. * * Scatter a buffer to the nodes, where every node gets - * a different chunk of the buffer, controlled by the slave. + * a different chunk of the buffer, controlled by the worker node. * * This is a collective call. */ diff --git a/testsuite/python/interactions_bonded_interface.py b/testsuite/python/interactions_bonded_interface.py index 16892f7cf05..cd7cf4f1b2e 100644 --- a/testsuite/python/interactions_bonded_interface.py +++ b/testsuite/python/interactions_bonded_interface.py @@ -252,6 +252,22 @@ def test_exceptions(self): espressomd.interactions.IBM_Triel( ind1=0, ind2=1, ind3=2, k1=1.1, k2=1.2, maxDist=1.6, elasticLaw='Unknown') + # sanity checks when removing bonds + self.system.bonded_inter.clear() + error_msg = 'The bonded interaction with the id 0 is not yet defined' + with self.assertRaisesRegex(ValueError, error_msg): + self.system.bonded_inter[0] + self.system.bonded_inter[0] = harm_bond1 + self.system.bonded_inter[0] + self.system.bonded_inter.remove(0) + with self.assertRaisesRegex(ValueError, error_msg): + self.system.bonded_inter[0] + self.system.bonded_inter[0] = harm_bond1 + self.system.bonded_inter[0] + del self.system.bonded_inter[0] + with self.assertRaisesRegex(ValueError, error_msg): + self.system.bonded_inter[0] + if __name__ == "__main__": ut.main() diff --git a/testsuite/python/mdanalysis.py b/testsuite/python/mdanalysis.py index 07d7b38b6d1..20648fa8ea4 100644 --- a/testsuite/python/mdanalysis.py +++ b/testsuite/python/mdanalysis.py @@ -44,7 +44,7 @@ class TestMDAnalysis(ut.TestCase): system.part.add(id=i, pos=[i, i % 2, 0], v=[0, i, -i], f=[1, 2 * i, 0], type=i % 2, q=i % 3 - 1) - bond = espressomd.interactions.HarmonicBond(k=1., r_0=1.5, r_cut=2.5) + bond = espressomd.interactions.HarmonicBond(k=1., r_0=1.2, r_cut=2.0) angle = espressomd.interactions.AngleCosine(bend=1., phi0=2 * np.pi / 3) dihe = espressomd.interactions.Dihedral(bend=1., mult=2, phase=np.pi / 3) system.bonded_inter.add(bond)