diff --git a/.github/actions/build_and_check/action.yml b/.github/actions/build_and_check/action.yml index 02831aaba25..6a4e4d6e71c 100644 --- a/.github/actions/build_and_check/action.yml +++ b/.github/actions/build_and_check/action.yml @@ -9,10 +9,6 @@ inputs: description: 'Whether to build with undefined behavior sanitizer' required: true default: 'false' - check_skip_long: # id of input - description: 'Whether to skip long python tests' - required: true - default: 'false' runs: using: "composite" steps: @@ -22,7 +18,7 @@ runs: pip3 install -c requirements.txt numpy cython h5py scipy shell: bash - run: | - export myconfig=maxset with_cuda=false test_timeout=800 with_asan=${{ inputs.asan }} with_ubsan=${{ inputs.ubsan }} check_skip_long=${{ inputs.check_skip_long }} + export myconfig=maxset with_cuda=false test_timeout=800 with_asan=${{ inputs.asan }} with_ubsan=${{ inputs.ubsan }} check_skip_long=true bash maintainer/CI/build_cmake.sh shell: bash # This is a workaround for the unfortunate interaction of MacOS and OpenMPI 4 diff --git a/.github/workflows/push_pull.yml b/.github/workflows/push_pull.yml index bdc28dd5220..82229ac6651 100644 --- a/.github/workflows/push_pull.yml +++ b/.github/workflows/push_pull.yml @@ -25,7 +25,6 @@ jobs: with: asan: false ubsan: false - check_skip_long: false sanitizer_check: permissions: @@ -46,7 +45,6 @@ jobs: with: asan: true ubsan: true - check_skip_long: true - name: Setting job link variable if: ${{ failure() }} run: | diff --git a/doc/sphinx/installation.rst b/doc/sphinx/installation.rst index 2f33faa6a56..b4cc715f873 100644 --- a/doc/sphinx/installation.rst +++ b/doc/sphinx/installation.rst @@ -108,20 +108,23 @@ CUDA SDK to make use of GPU computation: sudo apt install nvidia-cuda-toolkit +Later in the installation instructions, you will see CMake commands of the +form ``cmake ..`` with optional arguments, such as ``cmake .. -D WITH_CUDA=ON`` +to activate CUDA. These commands may need to be adapted depending on which +operating system and CUDA version you are using. + On Ubuntu 22.04, the default GCC compiler is too recent for nvcc and will fail to compile sources that rely on ``std::function``. You can either use GCC 10: .. code-block:: bash CC=gcc-10 CXX=g++-10 cmake .. -D WITH_CUDA=ON - make -j or alternatively install Clang 12 as a replacement for nvcc and GCC: .. code-block:: bash CC=clang-12 CXX=clang++-12 cmake .. -D WITH_CUDA=ON -D WITH_CUDA_COMPILER=clang - make -j On Ubuntu 20.04, the default GCC compiler is also too recent for nvcc and will generate compiler errors. You can either install an older version of GCC and diff --git a/doc/sphinx/inter_non-bonded.rst b/doc/sphinx/inter_non-bonded.rst index a008ae7f796..4b4e07ff2f8 100644 --- a/doc/sphinx/inter_non-bonded.rst +++ b/doc/sphinx/inter_non-bonded.rst @@ -44,7 +44,6 @@ Tabulated interaction Feature ``TABULATED`` required. - The interface for tabulated interactions are implemented in the :class:`~espressomd.interactions.TabulatedNonBonded` class. They can be configured via the following syntax:: @@ -52,7 +51,6 @@ via the following syntax:: system.non_bonded_inter[type1, type2].tabulated.set_params( min='min', max='max', energy='energy', force='force') - This defines an interaction between particles of the types ``type1`` and ``type2`` according to an arbitrary tabulated pair potential by linear interpolation. ``force`` specifies the tabulated forces and ``energy`` the energies as a function of the @@ -646,19 +644,6 @@ and involved types. The samples folder contains the script :file:`/samples/drude_bmimpf6.py` with a fully polarizable, coarse grained ionic liquid where this approach is applied. -To use the script, compile espresso with the following features: - -.. code-block:: c++ - - #define EXTERNAL_FORCES - #define MASS - #define THERMOSTAT_PER_PARTICLE - #define ROTATION - #define ROTATIONAL_INERTIA - #define ELECTROSTATICS - #define VIRTUAL_SITES_RELATIVE - #define LENNARD_JONES - #define THOLE .. _Anisotropic non-bonded interactions: diff --git a/src/core/Particle.hpp b/src/core/Particle.hpp index 4a4c8959666..c1f65411ea9 100644 --- a/src/core/Particle.hpp +++ b/src/core/Particle.hpp @@ -553,7 +553,6 @@ struct Particle { // NOLINT(bugprone-exception-escape) } auto const &ext_force() const { return p.ext_force; } auto &ext_force() { return p.ext_force; } - #else // EXTERNAL_FORCES constexpr bool has_fixed_coordinates() const { return false; } constexpr bool is_fixed_along(int const) const { return false; } diff --git a/src/core/constraints/Constraints.hpp b/src/core/constraints/Constraints.hpp index 11182f8f8c7..bfc9ca93178 100644 --- a/src/core/constraints/Constraints.hpp +++ b/src/core/constraints/Constraints.hpp @@ -41,29 +41,29 @@ template class Constraints { private: void reset_forces() const { - for (auto const &c : *this) { - c->reset_force(); + for (auto const &constraint : *this) { + constraint->reset_force(); } } container_type m_constraints; public: - void add(std::shared_ptr const &c) { - if (not c->fits_in_box(box_geo.length())) { + void add(std::shared_ptr const &constraint) { + if (not constraint->fits_in_box(box_geo.length())) { throw std::runtime_error("Constraint not compatible with box size."); } - assert(std::find(m_constraints.begin(), m_constraints.end(), c) == + assert(std::find(m_constraints.begin(), m_constraints.end(), constraint) == m_constraints.end()); - m_constraints.emplace_back(c); + m_constraints.emplace_back(constraint); on_constraint_change(); } - void remove(std::shared_ptr const &c) { - assert(std::find(m_constraints.begin(), m_constraints.end(), c) != + void remove(std::shared_ptr const &constraint) { + assert(std::find(m_constraints.begin(), m_constraints.end(), constraint) != m_constraints.end()); m_constraints.erase( - std::remove(m_constraints.begin(), m_constraints.end(), c), + std::remove(m_constraints.begin(), m_constraints.end(), constraint), m_constraints.end()); on_constraint_change(); } @@ -82,8 +82,8 @@ template class Constraints { for (auto &p : particles) { auto const pos = folded_position(p.pos(), box_geo); ParticleForce force{}; - for (auto const &c : *this) { - force += c->force(p, pos, t); + for (auto const &constraint : *this) { + force += constraint->force(p, pos, t); } p.f += force; diff --git a/src/core/constraints/HomogeneousMagneticField.cpp b/src/core/constraints/HomogeneousMagneticField.cpp index c45927ec0d2..a7a0b8e4247 100644 --- a/src/core/constraints/HomogeneousMagneticField.cpp +++ b/src/core/constraints/HomogeneousMagneticField.cpp @@ -28,7 +28,7 @@ namespace Constraints { ParticleForce HomogeneousMagneticField::force(const Particle &p, const Utils::Vector3d &, double) { -#if defined(ROTATION) && defined(DIPOLES) +#ifdef DIPOLES return {{}, vector_product(p.calc_dip(), m_field)}; #else return {}; diff --git a/src/core/grid_based_algorithms/lb_boundaries.cpp b/src/core/grid_based_algorithms/lb_boundaries.cpp index 818e2d2d416..14a1ff43b59 100644 --- a/src/core/grid_based_algorithms/lb_boundaries.cpp +++ b/src/core/grid_based_algorithms/lb_boundaries.cpp @@ -52,8 +52,6 @@ #include #include -using Utils::get_linear_index; - namespace LBBoundaries { std::vector> lbboundaries; @@ -87,8 +85,8 @@ bool sanity_check_mach_limit() { }); } -void ek_init_boundaries() { -#if defined(CUDA) && defined(EK_BOUNDARIES) +#if defined(EK_BOUNDARIES) +static void ek_init_boundaries() { int number_of_boundnodes = 0; std::vector host_wallcharge_species_density; @@ -164,8 +162,8 @@ void ek_init_boundaries() { ek_init_species_density_wallcharge(host_wallcharge_species_density.data(), wallcharge_species); } -#endif } +#endif // defined(EK_BOUNDARIES) /** Initialize boundary conditions for all constraints in the system. */ void lb_init_boundaries() { @@ -175,7 +173,9 @@ void lb_init_boundaries() { } #if defined(CUDA) #if defined(LB_BOUNDARIES_GPU) +#if defined(EK_BOUNDARIES) ek_init_boundaries(); +#endif unsigned number_of_boundnodes = 0; std::vector host_boundary_node_list; std::vector host_boundary_index_list; @@ -237,6 +237,7 @@ void lb_init_boundaries() { #endif // defined (CUDA) } else if (lattice_switch == ActiveLB::CPU) { #if defined(LB_BOUNDARIES) + using Utils::get_linear_index; boost::for_each(lbfields, [](auto &f) { f.boundary = 0; }); auto const node_pos = calc_node_pos(comm_cart); @@ -285,7 +286,6 @@ REGISTER_CALLBACK(lb_collect_boundary_forces_local) Utils::Vector3d lbboundary_get_force(LBBoundary const *lbb) { Utils::Vector3d force{}; -#if defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) auto const it = boost::find_if(lbboundaries, [lbb](std::shared_ptr const &i) { return i.get() == lbb; @@ -296,7 +296,7 @@ Utils::Vector3d lbboundary_get_force(LBBoundary const *lbb) { "system.lbboundaries."); std::vector forces(3 * lbboundaries.size()); if (lattice_switch == ActiveLB::GPU) { -#if defined(LB_BOUNDARIES_GPU) && defined(CUDA) +#if defined(LB_BOUNDARIES_GPU) lb_gpu_get_boundary_forces(forces); #endif } else if (lattice_switch == ActiveLB::CPU) { @@ -309,10 +309,9 @@ Utils::Vector3d lbboundary_get_force(LBBoundary const *lbb) { force[0] = forces[3 * container_index + 0]; force[1] = forces[3 * container_index + 1]; force[2] = forces[3 * container_index + 2]; -#endif return force; } -#endif /* LB_BOUNDARIES or LB_BOUNDARIES_GPU */ +#endif // defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) } // namespace LBBoundaries diff --git a/src/core/magnetostatics/barnes_hut_gpu_cuda.cu b/src/core/magnetostatics/barnes_hut_gpu_cuda.cu index f18a8fdd8dc..2c5e2ff90ee 100644 --- a/src/core/magnetostatics/barnes_hut_gpu_cuda.cu +++ b/src/core/magnetostatics/barnes_hut_gpu_cuda.cu @@ -709,12 +709,12 @@ __global__ __launch_bounds__(THREADS5, FACTOR5) void forceCalculationKernel( // calculated within the array dq[i], which will // be compared later with squared distance between the particle // and the cell depending on a cell level. - // Original tree box edge (2*radiusd) should be divided *0.5 + // Original tree box edge (2*radiusd) should be halved // as much as the tree depth takes place. dq[0] = radiusd * radiusd * *itolsqd; for (i = 1; i < maxdepthd; i++) { - dq[i] = dq[i - 1] * 0.25f; - dq[i - 1] += *epssqd; + dq[i] = dq[i - 1] * 0.25f; // halving of the squared distance + dq[i - 1] += *epssqd; // increase thickness of previous cell } dq[i - 1] += *epssqd; @@ -820,7 +820,7 @@ __global__ __launch_bounds__(THREADS5, FACTOR5) void forceCalculationKernel( #endif if (n != i) { - auto const d1 = sqrtf(tmp /*, 0.5f*/); + auto const d1 = sqrtf(tmp); auto const dd5 = __fdividef(1.0f, tmp * tmp * d1); auto b = 0.0f; auto b2 = 0.0f; @@ -891,7 +891,7 @@ __global__ __launch_bounds__(THREADS5, FACTOR5) void forceCalculationKernel( __global__ __launch_bounds__(THREADS5, FACTOR5) void energyCalculationKernel( float pf, float *energySum) { // NOTE: the algorithm of this kernel is almost identical to - // forceCalculationKernel. See comments there. + // @ref forceCalculationKernel. See comments there. int i, n, t; float dr[3], h[3], u[3], uc[3]; @@ -962,20 +962,16 @@ __global__ __launch_bounds__(THREADS5, FACTOR5) void energyCalculationKernel( dr[l] = -bhpara->r[3 * n + l] + bhpara->r[3 * i + l]; tmp += dr[l] * dr[l]; } + // check if all threads agree that cell is far enough away + // (or is a body) #if defined(__CUDACC__) && CUDA_VERSION >= 9000 if ((n < bhpara->nbodies) || - __all_sync( - __activemask(), - tmp >= dq[depth])) { // check if all threads agree that cell - // is far enough away (or is a body) + __all_sync(__activemask(), tmp >= dq[depth])) { #else - if ((n < bhpara->nbodies) || - __all(tmp >= - dq[depth])) { // check if all threads agree that cell - // is far enough away (or is a body) + if ((n < bhpara->nbodies) || __all(tmp >= dq[depth])) { #endif if (n != i) { - auto const d1 = sqrtf(tmp /*, 0.5f*/); + auto const d1 = sqrtf(tmp); auto const dd5 = __fdividef(1.0f, tmp * tmp * d1); auto b = 0.0f; for (int l = 0; l < 3; l++) { @@ -1275,4 +1271,4 @@ void fill_bh_data(float const *r, float const *dip, BHData const *bh_data) { cuda_safe_mem(cudaMemcpy(bh_data->u, dip, size, cudaMemcpyDeviceToDevice)); } -#endif // BARNES_HUT +#endif // DIPOLAR_BARNES_HUT diff --git a/src/core/magnetostatics/dds_gpu_cuda.cu b/src/core/magnetostatics/dds_gpu_cuda.cu index 5b76e38ca9e..b023c9e8ae8 100644 --- a/src/core/magnetostatics/dds_gpu_cuda.cu +++ b/src/core/magnetostatics/dds_gpu_cuda.cu @@ -152,7 +152,7 @@ __global__ void DipolarDirectSum_kernel_force(float pf, unsigned int n, // There is one thread per particle. Each thread computes interactions // with particles whose id is smaller than the thread id. // The force and torque of all the interaction partners of the current thread - // is atomically added to global results ad once. + // is atomically added to global results at once. // The result for the particle id equal to the thread id is atomically added // to global memory at the end. diff --git a/src/core/magnetostatics/dipoles_inline.hpp b/src/core/magnetostatics/dipoles_inline.hpp index a13f0a3b8d1..51ff6fd798b 100644 --- a/src/core/magnetostatics/dipoles_inline.hpp +++ b/src/core/magnetostatics/dipoles_inline.hpp @@ -51,7 +51,7 @@ struct ShortRangeForceKernel return {}; } -#ifdef P3M +#ifdef DP3M result_type operator()(std::shared_ptr const &ptr) const { auto const &actor = *ptr; return kernel_type{[&actor](Particle const &p1, Particle const &p2, @@ -60,7 +60,7 @@ struct ShortRangeForceKernel return actor.pair_force(p1, p2, d, dist2, dist); }}; } -#endif // P3M +#endif // DP3M result_type operator()(std::shared_ptr const &ptr) const { @@ -82,7 +82,7 @@ struct ShortRangeEnergyKernel return {}; } -#ifdef P3M +#ifdef DP3M result_type operator()(std::shared_ptr const &ptr) const { auto const &actor = *ptr; return kernel_type{[&actor](Particle const &p1, Particle const &p2, @@ -91,7 +91,7 @@ struct ShortRangeEnergyKernel return actor.pair_energy(p1, p2, d, dist2, dist); }}; } -#endif // P3M +#endif // DP3M result_type operator()(std::shared_ptr const &ptr) const { diff --git a/src/core/observables/ParticleTraits.hpp b/src/core/observables/ParticleTraits.hpp index 9e359401c1e..f11cce8d942 100644 --- a/src/core/observables/ParticleTraits.hpp +++ b/src/core/observables/ParticleTraits.hpp @@ -41,7 +41,7 @@ template <> struct traits { } auto charge(Particle const &p) const { return p.q(); } auto dipole_moment(Particle const &p) const { -#if defined(ROTATION) && defined(DIPOLES) +#ifdef DIPOLES return p.calc_dip(); #else return Utils::Vector3d{}; diff --git a/src/core/p3m/common.hpp b/src/core/p3m/common.hpp index b21f0ee8aeb..ab9cb917a8b 100644 --- a/src/core/p3m/common.hpp +++ b/src/core/p3m/common.hpp @@ -39,6 +39,9 @@ #include +#include +#include + /** This value indicates metallic boundary conditions. */ auto constexpr P3M_EPSILON_METALLIC = 0.0; @@ -46,10 +49,8 @@ auto constexpr P3M_EPSILON_METALLIC = 0.0; #include "LocalBox.hpp" -#include #include #include -#include namespace detail { /** @brief Index helpers for direct and reciprocal space. diff --git a/src/core/p3m/fft.cpp b/src/core/p3m/fft.cpp index b2aa88fc8b3..d488562c250 100644 --- a/src/core/p3m/fft.cpp +++ b/src/core/p3m/fft.cpp @@ -738,7 +738,7 @@ void fft_perform_back(double *data, bool check_complex, fft_data_struct &fft, for (int i = 0; i < fft.plan[1].new_size; i++) { fft.data_buf[i] = data[2 * i]; /* real value */ // Vincent: - if (check_complex && (data[2 * i + 1] > 1e-5)) { + if (check_complex and std::abs(data[2 * i + 1]) > 1e-5) { printf("Complex value is not zero (i=%d,data=%g)!!!\n", i, data[2 * i + 1]); if (i > 100) diff --git a/src/core/pressure.cpp b/src/core/pressure.cpp index f67defc2965..1f1f562c999 100644 --- a/src/core/pressure.cpp +++ b/src/core/pressure.cpp @@ -33,14 +33,11 @@ #include "event.hpp" #include "grid.hpp" #include "interactions.hpp" +#include "magnetostatics/dipoles.hpp" #include "nonbonded_interactions/nonbonded_interaction_data.hpp" #include "pressure_inline.hpp" -#include "virtual_sites.hpp" - #include "short_range_loop.hpp" - -#include "electrostatics/coulomb.hpp" -#include "magnetostatics/dipoles.hpp" +#include "virtual_sites.hpp" #include #include diff --git a/src/core/statistics.cpp b/src/core/statistics.cpp index 6d1506892ac..0dd94319fee 100644 --- a/src/core/statistics.cpp +++ b/src/core/statistics.cpp @@ -91,8 +91,8 @@ static Utils::Vector3d mpi_particle_momentum_local() { REGISTER_CALLBACK_REDUCTION(mpi_particle_momentum_local, std::plus()) -Utils::Vector3d calc_linear_momentum(int include_particles, - int include_lbfluid) { +Utils::Vector3d calc_linear_momentum(bool include_particles, + bool include_lbfluid) { Utils::Vector3d linear_momentum{}; if (include_particles) { linear_momentum += diff --git a/src/core/statistics.hpp b/src/core/statistics.hpp index 44faa758334..01fcc97e954 100644 --- a/src/core/statistics.hpp +++ b/src/core/statistics.hpp @@ -118,11 +118,10 @@ Utils::Vector3d angularmomentum(PartCfg &partCfg, int type); void momentofinertiamatrix(PartCfg &partCfg, int type, double *MofImatrix); /** Calculate total momentum of the system (particles & LB fluid). - * Inputs are bools to include particles and fluid in the linear momentum - * calculation - * @return Result for this processor + * @param include_particles Add particles momentum + * @param include_lbfluid Add LB fluid momentum */ -Utils::Vector3d calc_linear_momentum(int include_particles, - int include_lbfluid); +Utils::Vector3d calc_linear_momentum(bool include_particles, + bool include_lbfluid); #endif diff --git a/src/core/unit_tests/energy_test.cpp b/src/core/unit_tests/energy_test.cpp index 218687f97f9..f04aa0ace31 100644 --- a/src/core/unit_tests/energy_test.cpp +++ b/src/core/unit_tests/energy_test.cpp @@ -24,7 +24,7 @@ #include "Particle.hpp" #include "energy_inline.hpp" -#include "utils/Vector.hpp" +#include BOOST_AUTO_TEST_CASE(translational_kinetic_energy_) { // real particle diff --git a/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp b/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp index c9f8f3c137c..4151efc3f07 100644 --- a/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp +++ b/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp @@ -27,6 +27,7 @@ #include "errorhandling.hpp" #include "grid_based_algorithms/lb_interface.hpp" #include "virtual_sites/lb_inertialess_tracers.hpp" + #include void VirtualSitesInertialessTracers::after_force_calc() { @@ -51,9 +52,7 @@ void VirtualSitesInertialessTracers::after_force_calc() { } void VirtualSitesInertialessTracers::after_lb_propagation(double time_step) { -#ifdef VIRTUAL_SITES_INERTIALESS_TRACERS IBM_UpdateParticlePositions(cell_structure.local_particles(), time_step, this_node); -#endif } -#endif +#endif // VIRTUAL_SITES_INERTIALESS_TRACERS diff --git a/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp b/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp index c70b207430c..6a74f5764b6 100644 --- a/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp +++ b/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp @@ -20,10 +20,11 @@ #define VIRTUAL_SITES_VIRTUAL_SITES_INERTIALESS_TRACERS_HPP #include "config.hpp" -#ifdef VIRTUAL_SITES -#include "VirtualSites.hpp" #ifdef VIRTUAL_SITES_INERTIALESS_TRACERS + +#include "VirtualSites.hpp" + /** @brief Virtual sites which are advected with an lb fluid. Forces on them are * instantaneously transferred to the fluid */ @@ -32,6 +33,5 @@ class VirtualSitesInertialessTracers : public VirtualSites { void after_lb_propagation(double time_step) override; }; -#endif -#endif +#endif // VIRTUAL_SITES_INERTIALESS_TRACERS #endif diff --git a/src/core/virtual_sites/lb_inertialess_tracers.cpp b/src/core/virtual_sites/lb_inertialess_tracers.cpp index 113c21ca291..87f29d1a6d8 100644 --- a/src/core/virtual_sites/lb_inertialess_tracers.cpp +++ b/src/core/virtual_sites/lb_inertialess_tracers.cpp @@ -306,4 +306,4 @@ void ParticleVelocitiesFromLB_CPU() { } } } -#endif +#endif // VIRTUAL_SITES_INERTIALESS_TRACERS diff --git a/src/python/espressomd/drude_helpers.py b/src/python/espressomd/drude_helpers.py index 40337476ab7..ee0605dcd21 100644 --- a/src/python/espressomd/drude_helpers.py +++ b/src/python/espressomd/drude_helpers.py @@ -81,13 +81,16 @@ def add_drude_particle_to_core(self, system, harmonic_bond, k = harmonic_bond.params["k"] q_drude = -1.0 * pow(k * alpha / coulomb_prefactor, 0.5) - if has_features("PARTICLE_ANISOTROPY"): - gamma_off = [0.0, 0.0, 0.0] - else: - gamma_off = 0.0 + if has_features("THERMOSTAT_PER_PARTICLE"): + if has_features("PARTICLE_ANISOTROPY"): + gamma_off = [0.0, 0.0, 0.0] + else: + gamma_off = 0.0 drude_part = system.part.add(pos=p_core.pos, type=type_drude, - q=q_drude, mass=mass_drude, gamma=gamma_off) + q=q_drude, mass=mass_drude) + if has_features("THERMOSTAT_PER_PARTICLE"): + drude_part.gamma = gamma_off id_drude = drude_part.id if verbose: @@ -98,8 +101,8 @@ def add_drude_particle_to_core(self, system, harmonic_bond, p_core.mass -= mass_drude p_core.add_bond((harmonic_bond, id_drude)) p_core.add_bond((thermalized_bond, id_drude)) - - p_core.gamma = gamma_off + if has_features("THERMOSTAT_PER_PARTICLE"): + p_core.gamma = gamma_off if type_drude in self.drude_dict and not ( self.drude_dict[type_drude]["q"] == q_drude and diff --git a/src/script_interface/tests/GlobalContext_test.cpp b/src/script_interface/tests/GlobalContext_test.cpp index 19bee7ff1f0..b5556b2d18e 100644 --- a/src/script_interface/tests/GlobalContext_test.cpp +++ b/src/script_interface/tests/GlobalContext_test.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -49,7 +50,7 @@ struct Dummy : si::ObjectHandle { static const boost::string_ref parameter_names[] = {"id", "object_param"}; return Utils::make_const_span(parameter_names, - std::min(params.size(), 2lu)); + std::min(params.size(), std::size_t{2u})); } }; diff --git a/src/script_interface/tests/LocalContext_test.cpp b/src/script_interface/tests/LocalContext_test.cpp index 60a8ed88df8..9122ffa0fee 100644 --- a/src/script_interface/tests/LocalContext_test.cpp +++ b/src/script_interface/tests/LocalContext_test.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -49,7 +50,7 @@ struct Dummy : si::ObjectHandle { static const boost::string_ref parameter_names[] = {"id", "object_param"}; return Utils::make_const_span(parameter_names, - std::min(params.size(), 2lu)); + std::min(params.size(), std::size_t{2u})); } }; diff --git a/src/shapes/include/shapes/Union.hpp b/src/shapes/include/shapes/Union.hpp index 55c5e5b85bc..adc62e51059 100644 --- a/src/shapes/include/shapes/Union.hpp +++ b/src/shapes/include/shapes/Union.hpp @@ -35,12 +35,12 @@ namespace Shapes { class Union : public Shape { public: - void add(std::shared_ptr const &s) { - m_shapes.emplace_back(s); + void add(std::shared_ptr const &shape) { + m_shapes.emplace_back(shape); } - void remove(std::shared_ptr const &s) { - m_shapes.erase(std::remove(m_shapes.begin(), m_shapes.end(), s), + void remove(std::shared_ptr const &shape) { + m_shapes.erase(std::remove(m_shapes.begin(), m_shapes.end(), shape), m_shapes.end()); } @@ -55,10 +55,10 @@ class Union : public Shape { void calculate_dist(Utils::Vector3d const &pos, double &dist, Utils::Vector3d &vec) const override { auto dist_compare = [&pos](std::pair const &res, - std::shared_ptr const &s) { + std::shared_ptr const &shape) { double d; Utils::Vector3d vec; - (*s).calculate_dist(pos, d, vec); + shape->calculate_dist(pos, d, vec); if (d < 0.0) throw std::domain_error( "Distance to Union not well-defined for given position!"); @@ -76,7 +76,7 @@ class Union : public Shape { bool is_inside(Utils::Vector3d const &pos) const override { return boost::algorithm::any_of( - m_shapes, [&pos](auto const &s) { return s->is_inside(pos); }); + m_shapes, [&pos](auto const &shape) { return shape->is_inside(pos); }); } private: diff --git a/src/utils/include/utils/u32_to_u64.hpp b/src/utils/include/utils/u32_to_u64.hpp index f33b2f0c21c..f35d2369124 100644 --- a/src/utils/include/utils/u32_to_u64.hpp +++ b/src/utils/include/utils/u32_to_u64.hpp @@ -19,7 +19,7 @@ #ifndef UTILS_U32_TO_U64_HPP #define UTILS_U32_TO_U64_HPP -#include +#include #include namespace Utils { @@ -33,4 +33,4 @@ constexpr inline std::pair u64_to_u32(uint64_t in) { } // namespace Utils -#endif // ESPRESSO_U32_TO_U64_HPP +#endif diff --git a/src/utils/tests/serialization_test.cpp b/src/utils/tests/serialization_test.cpp index 67fe91d5fb4..6f9dad3630e 100644 --- a/src/utils/tests/serialization_test.cpp +++ b/src/utils/tests/serialization_test.cpp @@ -208,11 +208,23 @@ auto sorted_view(InputIt const &buffer_it) { return subset; } +/** + * @brief Simplistic test for endianness. + * Replace with @c std::endian once ESPResSo becomes a C++20 project. + */ +bool is_big_endian() { +#ifdef __BYTE_ORDER__ + return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; +#else + return false; +#endif +} + BOOST_AUTO_TEST_CASE(serialization_level_test) { boost::mpi::communicator comm; auto const buffer = create_mpi_archive(comm); - /* Serialization should produce the following bytestring: + /* Serialization should produce the following bytestring (little-endian): * 3 0 0 0 0 0 0 0 * 4 0 0 0 * 5 0 0 0 @@ -267,7 +279,10 @@ BOOST_AUTO_TEST_CASE(mpi_archive_test) { BOOST_TEST(buffer_vector == buffer_ref, boost::test_tools::per_element()); BOOST_TEST(buffer_storage == buffer_ref, boost::test_tools::per_element()); BOOST_TEST(buffer_quat == buffer_ref, boost::test_tools::per_element()); - BOOST_TEST(buffer_cv[0] == Testing::N); + auto const index_lsb = (is_big_endian()) ? 1 : 0; + auto const index_hsb = (is_big_endian()) ? 0 : 1; + BOOST_TEST(buffer_cv[index_lsb] == Testing::N); + BOOST_TEST(buffer_cv[index_hsb] == 0); buffer_cv.erase(buffer_cv.begin()); buffer_cv.erase(buffer_cv.begin()); BOOST_TEST(buffer_cv == buffer_ref, boost::test_tools::per_element()); diff --git a/src/utils/tests/u32_to_u64_test.cpp b/src/utils/tests/u32_to_u64_test.cpp index 5e7c0bdf3a1..8daaeee7e70 100644 --- a/src/utils/tests/u32_to_u64_test.cpp +++ b/src/utils/tests/u32_to_u64_test.cpp @@ -25,7 +25,7 @@ #include BOOST_AUTO_TEST_CASE(u32_to_u64) { - constexpr const uint64_t expected = (4ul << 32) | (11ul); + constexpr const uint64_t expected = (uint64_t{4ul} << 32) | (11ul); BOOST_CHECK(expected == Utils::u32_to_u64(4u, 11u)); } diff --git a/testsuite/python/bond_breakage.py b/testsuite/python/bond_breakage.py index 92da7e1ec5f..01ea4283b9a 100644 --- a/testsuite/python/bond_breakage.py +++ b/testsuite/python/bond_breakage.py @@ -216,6 +216,7 @@ def tearDown(self): self.system.bonded_inter.clear() self.system.thermostat.turn_off() + @utx.skipIfMissingFeatures(["COLLISION_DETECTION"]) def test_center_bonds(self): harm = espressomd.interactions.HarmonicBond(k=1.0, r_0=0.0, r_cut=5) @@ -244,7 +245,8 @@ def test_center_bonds(self): bonds_count = self.count_bonds(pairs) np.testing.assert_equal(bonds_dist, bonds_count) - @utx.skipIfMissingFeatures("VIRTUAL_SITES_RELATIVE") + @utx.skipIfMissingFeatures( + ["VIRTUAL_SITES_RELATIVE", "COLLISION_DETECTION"]) def test_vs_bonds(self): harm = espressomd.interactions.HarmonicBond(k=1.0, r_0=0.0, r_cut=5) diff --git a/testsuite/python/collision_detection.py b/testsuite/python/collision_detection.py index 16b4236d332..0c959c35857 100644 --- a/testsuite/python/collision_detection.py +++ b/testsuite/python/collision_detection.py @@ -464,7 +464,7 @@ def test_glue_to_surface(self): self.run_test_glue_to_surface_for_pos( np.array((0.2, 0, 0)), np.array((0.95, 0, 0)), np.array((0.7, 0, 0))) - @utx.skipIfMissingFeatures("VIRTUAL_SITES_RELATIVE") + @utx.skipIfMissingFeatures(["LENNARD_JONES", "VIRTUAL_SITES_RELATIVE"]) def test_glue_to_surface_random(self): """Integrate lj liquid and check that no double bonds are formed and the number of bonds fits the number of virtual sites diff --git a/testsuite/python/constraint_shape_based.py b/testsuite/python/constraint_shape_based.py index 48233a9b6df..a0ee72d187a 100644 --- a/testsuite/python/constraint_shape_based.py +++ b/testsuite/python/constraint_shape_based.py @@ -30,7 +30,7 @@ import tests_common -@utx.skipIfMissingFeatures(["LENNARD_JONES_GENERIC"]) +@utx.skipIfMissingFeatures(["LENNARD_JONES", "LENNARD_JONES_GENERIC"]) class ShapeBasedConstraintTest(ut.TestCase): box_l = 30. diff --git a/testsuite/python/dipolar_direct_summation.py b/testsuite/python/dipolar_direct_summation.py index 5d98bf4ecb5..d99ad683939 100644 --- a/testsuite/python/dipolar_direct_summation.py +++ b/testsuite/python/dipolar_direct_summation.py @@ -121,6 +121,7 @@ def fcs_data(self): @ut.skipIf(system.cell_system.get_state()["n_nodes"] > 1, "Skipping test: only runs for n_nodes == 1") + @utx.skipIfMissingFeatures(["LENNARD_JONES"]) def test_gen_reference_data(self): filepaths = ('dipolar_direct_summation_energy.npy', 'dipolar_direct_summation_arrays.npy') diff --git a/testsuite/python/integrator_npt.py b/testsuite/python/integrator_npt.py index 5d90b311fae..4371f9b7703 100644 --- a/testsuite/python/integrator_npt.py +++ b/testsuite/python/integrator_npt.py @@ -71,7 +71,7 @@ def test_00_integrator_recovery(self): # get the equilibrium box length for the chosen NpT parameters system.integrator.run(500) # catch unstable simulation early (when the DP3M test case ran first) - assert system.box_l[0] < 20. + assert system.box_l[0] < 20., "NpT simulation is unstable" system.integrator.run(1500) box_l_ref = system.box_l[0] diff --git a/testsuite/python/lees_edwards.py b/testsuite/python/lees_edwards.py index fb6c64f0435..04f412e2d10 100644 --- a/testsuite/python/lees_edwards.py +++ b/testsuite/python/lees_edwards.py @@ -343,7 +343,7 @@ def test_distance_vel_diff(self): np.copy(system.velocity_difference(p1, p2)), np.copy(p2.v - p1.v) - system.lees_edwards.shear_velocity * shear_axis) - @utx.skipIfMissingFeatures("EXTERNAL_FORCES") + @utx.skipIfMissingFeatures(["EXTERNAL_FORCES", "SOFT_SPHERE"]) def test_interactions(self): """ We place two particles crossing a boundary and connect them with an diff --git a/testsuite/python/long_range_actors.py b/testsuite/python/long_range_actors.py index 1682c16059b..f1cb034930a 100644 --- a/testsuite/python/long_range_actors.py +++ b/testsuite/python/long_range_actors.py @@ -284,13 +284,13 @@ def check_p3m_tuning_errors(self, p3m): self.assertFalse(p3m.is_tuned) self.assertEqual(len(self.system.actors), 0) - @utx.skipIfMissingFeatures(["P3M"]) + @utx.skipIfMissingFeatures(["P3M", "NPT"]) def test_p3m_cpu_tuning_errors(self): self.add_charged_particles() p3m = espressomd.electrostatics.P3M(prefactor=1., accuracy=1e-3) self.check_p3m_tuning_errors(p3m) - @utx.skipIfMissingFeatures(["DP3M"]) + @utx.skipIfMissingFeatures(["DP3M", "NPT"]) def test_dp3m_cpu_tuning_errors(self): self.add_magnetic_particles() dp3m = espressomd.magnetostatics.DipolarP3M( diff --git a/testsuite/python/mmm1d.py b/testsuite/python/mmm1d.py index b270fe01ad9..cd1c2655cb1 100644 --- a/testsuite/python/mmm1d.py +++ b/testsuite/python/mmm1d.py @@ -111,7 +111,7 @@ def test_bjerrum_length_change(self): def test_infinite_wire(self): """ For an infinite wire, the energy per ion is :math:`MC\\frac{q}{a}` - with :math:`M = - \\ln{2}` the 1D Madelung constant, :math:`C` + with :math:`M = - 2\\ln{2}` the 1D Madelung constant, :math:`C` the electrostatics prefactor, :math:`q` the ion charge and :math:`a` the lattice constant. Likewise, the pressure for one ion can be derived as :math:`MC\\frac{q}{aV}` with @@ -131,9 +131,8 @@ def test_infinite_wire(self): energy = self.system.analysis.energy()["coulomb"] p_scalar = self.system.analysis.pressure()["coulomb"] p_tensor = self.system.analysis.pressure_tensor()["coulomb"] - ref_energy = -np.log(2.) - np.testing.assert_allclose(energy / n_part, ref_energy, - atol=0., rtol=5e-7) + ref_energy = -np.log(2.) * n_part + np.testing.assert_allclose(energy, ref_energy, atol=0., rtol=5e-7) np.testing.assert_allclose(p_scalar, 0., atol=1e-12) np.testing.assert_allclose(p_tensor, 0., atol=1e-12) diff --git a/testsuite/python/random_pairs.py b/testsuite/python/random_pairs.py index ffc66eb291d..d23959c646b 100644 --- a/testsuite/python/random_pairs.py +++ b/testsuite/python/random_pairs.py @@ -20,6 +20,7 @@ import unittest as ut import espressomd import numpy as np +import scipy.spatial import itertools import collections import tests_common @@ -38,23 +39,31 @@ class RandomPairTest(ut.TestCase): system = espressomd.System(box_l=[10., 15., 15.]) def setUp(self): - s = self.system - s.time_step = .1 - s.cell_system.skin = 0.0 - s.min_global_cut = 1.5 - n_part = 500 + system = self.system + system.time_step = .1 + system.cell_system.skin = 0.0 + system.min_global_cut = 1.5 + n_part = 400 np.random.seed(2) - s.part.add(pos=s.box_l * np.random.random((n_part, 3))) + positions = system.box_l * np.random.random((n_part, 3)) + system.part.add(pos=positions) self.all_pairs = [] - dist_func = self.system.distance - for pair in self.system.part.pairs(): - if dist_func(pair[0], pair[1]) < 1.5: - self.all_pairs.append((pair[0].id, pair[1].id)) - - self.all_pairs = set(self.all_pairs) + def euclidean_pbc(a, b, box_l): + vec = np.fmod(a - b + box_l, box_l) + for i in range(3): + if vec[i] > box_l[i] / 2.: + vec[i] -= box_l[i] + return np.linalg.norm(vec) + + dist_mat = scipy.spatial.distance.cdist( + positions, positions, metric=euclidean_pbc, + box_l=np.copy(system.box_l)) + diag_mask = np.logical_not(np.eye(n_part, dtype=bool)) + dist_crit = (dist_mat < 1.5) * diag_mask + self.all_pairs = list(zip(*np.nonzero(np.triu(dist_crit)))) self.assertGreater(len(self.all_pairs), 0) def tearDown(self): diff --git a/testsuite/python/save_checkpoint.py b/testsuite/python/save_checkpoint.py index f87f1a4a0d6..8ab528feea8 100644 --- a/testsuite/python/save_checkpoint.py +++ b/testsuite/python/save_checkpoint.py @@ -76,8 +76,10 @@ lbf_actor = None if 'LB.CPU' in modes: lbf_actor = espressomd.lb.LBFluid + has_lbb = espressomd.has_features("LB_BOUNDARIES") elif 'LB.GPU' in modes and espressomd.gpu_available(): lbf_actor = espressomd.lb.LBFluidGPU + has_lbb = espressomd.has_features("LB_BOUNDARIES_GPU") if lbf_actor: lbf_cpt_mode = 0 if 'LB.ASCII' in modes else 1 lbf = lbf_actor(agrid=0.5, visc=1.3, dens=1.5, tau=0.01, gamma_odd=0.2, @@ -85,8 +87,7 @@ system.actors.add(lbf) if 'THERM.LB' in modes: system.thermostat.set_lb(LB_fluid=lbf, seed=23, gamma=2.0) - if (espressomd.has_features( - "LB_BOUNDARIES") or espressomd.has_features("LB_BOUNDARIES_GPU")): + if has_lbb: system.lbboundaries.add(espressomd.lbboundaries.LBBoundary( shape=espressomd.shapes.Wall(normal=(1, 0, 0), dist=0.5), velocity=(1e-4, 1e-4, 0))) system.lbboundaries.add(espressomd.lbboundaries.LBBoundary( diff --git a/testsuite/python/test_checkpoint.py b/testsuite/python/test_checkpoint.py index 7aa9bc86ed9..4132418aa92 100644 --- a/testsuite/python/test_checkpoint.py +++ b/testsuite/python/test_checkpoint.py @@ -44,6 +44,9 @@ modes = config.get_modes() has_lb_mode = 'LB.CPU' in modes or 'LB.GPU' in modes and is_gpu_available has_p3m_mode = 'P3M.CPU' in modes or 'P3M.GPU' in modes and is_gpu_available +has_lbb = ('LB.CPU' in modes and espressomd.has_features("LB_BOUNDARIES") or + 'LB.GPU' in modes and espressomd.has_features("LB_BOUNDARIES_GPU") + and espressomd.gpu_available()) class CheckpointTest(ut.TestCase): @@ -654,9 +657,7 @@ def test_exclusions(self): self.assertEqual(list(system.part.by_id(1).exclusions), [2]) self.assertEqual(list(system.part.by_id(2).exclusions), [0, 1]) - @ut.skipIf(not has_lb_mode or not (espressomd.has_features("LB_BOUNDARIES") - or espressomd.has_features("LB_BOUNDARIES_GPU")), - "Missing features") + @ut.skipIf(not has_lbb, "Missing features") def test_lb_boundaries(self): # check boundary objects self.assertEqual(len(system.lbboundaries), 2) @@ -735,6 +736,7 @@ def test_constraints(self): if self.n_nodes == 1: union = c[7].shape self.assertIsInstance(union, espressomd.shapes.Union) + self.assertEqual(c[7].particle_type, 2) self.assertEqual(len(union), 2) wall1, wall2 = union.call_method('get_elements') self.assertIsInstance(wall1, espressomd.shapes.Wall)