Skip to content

Commit 65c411a

Browse files
committed
Performance: short range forces low hanging fruits
- avoid a few constructions of ParticleForce - avoid calls to npt and gay-berne if not active - in the linked cell algorithm, first do cell-internal interactions to have better memory locality. Improves thins by ~5% on my system (Intel)
1 parent 17a181a commit 65c411a

9 files changed

Lines changed: 71 additions & 33 deletions

File tree

src/core/BoxGeometry.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,9 @@ class BoxGeometry {
207207
* periodic images, i.e. <tt>a - b</tt>.
208208
*/
209209
template <typename T>
210-
Utils::Vector<T, 3> get_mi_vector(const Utils::Vector<T, 3> &a,
211-
const Utils::Vector<T, 3> &b) const {
210+
[[gnu::always_inline]] inline Utils::Vector<T, 3>
211+
get_mi_vector(const Utils::Vector<T, 3> &a,
212+
const Utils::Vector<T, 3> &b) const {
212213
if (type() == BoxType::LEES_EDWARDS) {
213214
auto const shear_plane_normal = lees_edwards_bc().shear_plane_normal;
214215
auto a_tmp = a;

src/core/algorithm/link_cell.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ void link_cell(CellIterator first, CellIterator last,
4040
for (auto jt = std::next(it); jt != local_particles.end(); ++jt) {
4141
pair_kernel(p1, *jt);
4242
}
43-
43+
}
44+
for (auto it = local_particles.begin(); it != local_particles.end(); ++it) {
45+
auto &p1 = *it;
4446
/* Pairs with neighbors */
4547
for (auto &neighbor : cell->neighbors().red()) {
4648
for (auto &p2 : neighbor->particles()) {

src/core/cell_system/CellStructure.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ namespace detail {
115115
// NOLINTNEXTLINE(bugprone-exception-escape)
116116
struct MinimalImageDistance {
117117
BoxGeometry const box;
118-
119-
Distance operator()(Particle const &p1, Particle const &p2) const {
118+
inline Distance operator()(Particle const &p1, Particle const &p2) const {
120119
return Distance(box.get_mi_vector(p1.pos(), p2.pos()));
121120
}
122121
};

src/core/constraints/ShapeBasedConstraint.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include "errorhandling.hpp"
3030
#include "forces_inline.hpp"
3131
#include "nonbonded_interactions/nonbonded_interaction_data.hpp"
32+
#ifdef GAY_BERNE
33+
#include "nonbonded_interactions/gay_berne.hpp"
34+
#endif
3235
#include "system/System.hpp"
3336
#include "thermostat.hpp"
3437

@@ -111,7 +114,12 @@ ParticleForce ShapeBasedConstraint::force(Particle const &p,
111114
pf.f += thole_pair_force(p, part_rep, ia_params, dist_vec, dist,
112115
*system.bonded_ias, get_ptr(coulomb_kernel));
113116
#endif
114-
pf += calc_non_central_force(p, part_rep, ia_params, dist_vec, dist);
117+
#ifdef GAY_BERNE
118+
if (gb_active(ia_params)) {
119+
pf +=
120+
gb_pair_force(p.quat(), part_rep.quat(), ia_params, dist_vec, dist);
121+
}
122+
#endif
115123

116124
#ifdef DPD
117125
if (system.thermostat->thermo_switch & THERMO_DPD) {
@@ -130,7 +138,12 @@ ParticleForce ShapeBasedConstraint::force(Particle const &p,
130138
pf.f += thole_pair_force(p, part_rep, ia_params, dist_vec, -dist,
131139
*system.bonded_ias, get_ptr(coulomb_kernel));
132140
#endif
133-
pf += calc_non_central_force(p, part_rep, ia_params, dist_vec, -dist);
141+
#ifdef GAY_BERNE
142+
if (gb_active(ia_params)) {
143+
pf += gb_pair_force(p.quat(), part_rep.quat(), ia_params, dist_vec,
144+
-dist);
145+
}
146+
#endif
134147

135148
#ifdef DPD
136149
if (system.thermostat->thermo_switch & THERMO_DPD) {

src/core/forces_inline.hpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
#include "errorhandling.hpp"
6868
#include "exclusions.hpp"
6969
#include "thermostat.hpp"
70+
#ifdef NPT
71+
#include "npt.hpp"
72+
#endif
7073

7174
#include <utils/Vector.hpp>
7275

@@ -140,20 +143,6 @@ inline Utils::Vector3d calc_central_radial_force(IA_parameters const &ia_params,
140143
return force_factor * d;
141144
}
142145

143-
inline ParticleForce calc_non_central_force(Particle const &p1,
144-
Particle const &p2,
145-
IA_parameters const &ia_params,
146-
Utils::Vector3d const &d,
147-
double const dist) {
148-
149-
ParticleForce pf{};
150-
/* Gay-Berne */
151-
#ifdef GAY_BERNE
152-
pf += gb_pair_force(p1.quat(), p2.quat(), ia_params, d, dist);
153-
#endif
154-
return pf;
155-
}
156-
157146
inline void apply_opposing_force(ParticleForce &pf, Utils::Vector3d const &d) {
158147
#ifdef ROTATION
159148
// if torque is a null vector, the opposing torque is a null vector too
@@ -203,11 +192,11 @@ inline void add_non_bonded_pair_force(
203192
if (do_nonbonded(p1, p2)) {
204193
#endif
205194
pf.f += calc_central_radial_force(ia_params, d, dist);
206-
#ifdef THOLE
207-
pf.f += thole_pair_force(p1, p2, ia_params, d, dist, bonded_ias,
208-
coulomb_kernel);
195+
#ifdef GAY_BERNE
196+
if (gb_active(ia_params)) {
197+
pf += gb_pair_force(p1.quat(), p2.quat(), ia_params, d, dist);
198+
}
209199
#endif
210-
pf += calc_non_central_force(p1, p2, ia_params, d, dist);
211200
#ifdef EXCLUSIONS
212201
}
213202
#endif
@@ -219,7 +208,9 @@ inline void add_non_bonded_pair_force(
219208
/* electrostatic is calculated by energy */
220209
/*********************************************************************/
221210
#ifdef NPT
222-
npt_add_virial_force_contribution(pf.f, d);
211+
if (npt_active()) {
212+
npt_add_virial_force_contribution(pf.f, d);
213+
}
223214
#endif
224215

225216
/***********************************************/
@@ -231,9 +222,15 @@ inline void add_non_bonded_pair_force(
231222
auto const q1q2 = p1.q() * p2.q();
232223
if (q1q2 != 0. and coulomb_kernel != nullptr) {
233224
pf.f += (*coulomb_kernel)(q1q2, d, dist);
225+
#ifdef THOLE
226+
pf.f += thole_pair_force(p1, p2, ia_params, d, dist, bonded_ias,
227+
coulomb_kernel);
228+
#endif
234229
#ifdef NPT
235-
npt_add_virial_diagonalSum_contribution(
236-
(*coulomb_u_kernel)(p1, p2, q1q2, d, dist));
230+
if (npt_active()) {
231+
npt_add_virial_diagonalSum_contribution(
232+
(*coulomb_u_kernel)(p1, p2, q1q2, d, dist));
233+
}
237234
#endif
238235
#ifdef P3M
239236
if (elc_kernel)
@@ -345,7 +342,9 @@ inline bool add_bonded_two_body_force(
345342
p2.force() -= result.value();
346343

347344
#ifdef NPT
348-
npt_add_virial_force_contribution(result.value(), dx);
345+
if (npt_active()) {
346+
npt_add_virial_force_contribution(result.value(), dx);
347+
}
349348
#endif
350349
return false;
351350
}

src/core/nonbonded_interactions/gay_berne.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545

4646
#include <cmath>
4747

48+
/** Check if Gay-Berne interaction is active */
49+
inline bool gb_active(IA_parameters const &ia_params) {
50+
return ia_params.gay_berne.cut != INACTIVE_CUTOFF;
51+
}
52+
4853
/** Calculate Gay-Berne force and torques */
4954
inline ParticleForce gb_pair_force(Utils::Quaternion<double> const &qi,
5055
Utils::Quaternion<double> const &qj,

src/core/npt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,5 @@ void System::System::npt_add_virial_contribution(Utils::Vector3d const &force,
148148
npt_inst_pressure->p_vir += hadamard_product(force, d);
149149
}
150150
}
151+
151152
#endif // NPT

src/core/npt.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include <cstddef>
3535
#include <vector>
3636

37+
#include "PropagationMode.hpp"
38+
#include "integrators/Propagation.hpp"
39+
#include "system/System.hpp"
40+
3741
namespace System {
3842
class System;
3943
} // namespace System
@@ -99,4 +103,11 @@ struct InstantaneousPressure {
99103
Utils::Vector3d p_vel = {0., 0., 0.};
100104
};
101105

106+
/** Check if NPT integration is active. */
107+
inline bool npt_active() {
108+
auto const &system = ::System::get_system();
109+
return (system.propagation->integ_switch == INTEG_METHOD_NPT_ISO_AND) ||
110+
(system.propagation->integ_switch == INTEG_METHOD_NPT_ISO_MTK);
111+
}
112+
102113
#endif // NPT

src/core/pressure_inline.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
#include "errorhandling.hpp"
3434
#include "exclusions.hpp"
3535
#include "forces_inline.hpp"
36+
#ifdef GAY_BERNE
37+
#include "nonbonded_interactions/gay_berne.hpp"
38+
#endif
3639

3740
#include <utils/Vector.hpp>
3841
#include <utils/math/tensor_product.hpp>
@@ -67,12 +70,16 @@ inline void add_non_bonded_pair_virials(
6770
if (do_nonbonded(p1, p2))
6871
#endif
6972
{
70-
auto const force = calc_central_radial_force(ia_params, d, dist) +
73+
auto force = calc_central_radial_force(ia_params, d, dist);
7174
#ifdef THOLE
72-
thole_pair_force(p1, p2, ia_params, d, dist, bonded_ias,
73-
kernel_forces) +
75+
force +=
76+
thole_pair_force(p1, p2, ia_params, d, dist, bonded_ias, kernel_forces);
77+
#endif
78+
#ifdef GAY_BERNE
79+
if (gb_active(ia_params)) {
80+
force += gb_pair_force(p1.quat(), p2.quat(), ia_params, d, dist).f;
81+
}
7482
#endif
75-
calc_non_central_force(p1, p2, ia_params, d, dist).f;
7683
auto const stress = Utils::tensor_product(d, force);
7784
obs_pressure.add_non_bonded_contribution(p1.type(), p2.type(), p1.mol_id(),
7885
p2.mol_id(), flatten(stress));

0 commit comments

Comments
 (0)