ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
energy_cabana.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include <config/config.hpp>
23
24#include "aosoa_pack.hpp"
25#include "energy_inline.hpp"
27
28#include <utils/Vector.hpp>
29
30#include <Cabana_Core.hpp>
31
32#include <omp.h>
33
34#include <cstddef>
35#include <memory>
36#include <optional>
37#include <variant>
38#include <vector>
39
41 std::size_t n_bonded; // initialized by bonded_ias->get_next_key()
42 std::size_t n_types; // max_seen_particle_type
43 std::size_t off_bonded = 0; // [0, n_bonded)
44 std::size_t off_nb_inter;
45 std::size_t off_nb_intra;
46 std::size_t off_coulomb;
47 std::size_t off_dipolar;
48 std::size_t total;
49
59
61 nb_inter_idx(int t1, int t2) const {
62 return off_nb_inter +
63 Utils::lower_triangular(std::max(t1, t2), std::min(t1, t2));
64 }
65
67 nb_intra_idx(int t1, int t2) const {
68 return off_nb_intra +
69 Utils::lower_triangular(std::max(t1, t2), std::min(t1, t2));
70 }
71
72 KOKKOS_INLINE_FUNCTION std::size_t dipolar_idx() const { return off_dipolar; }
73 KOKKOS_INLINE_FUNCTION std::size_t coulomb_idx() const { return off_coulomb; }
74 KOKKOS_INLINE_FUNCTION std::size_t bonded_idx(int b) const {
75 return off_bonded + b;
76 }
77};
78
80 using memory_space = Kokkos::HostSpace;
87 std::vector<Particle *> const &unique_particles;
88 Kokkos::View<double **, Kokkos::LayoutRight, memory_space> local_energy;
91 Kokkos::View<int *, Kokkos::LayoutRight, memory_space> mol_id_view;
93
112
113 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t i,
114 std::size_t j) const {
115 auto const d = box_geo.get_mi_vector(
116 aosoa.position(i, 0), aosoa.position(i, 1), aosoa.position(i, 2),
117 aosoa.position(j, 0), aosoa.position(j, 1), aosoa.position(j, 2));
118 auto const dist_sq = d.norm2();
120 return;
121 auto const dist = std::sqrt(dist_sq);
122
123 auto const t1 = aosoa.type(i);
124 auto const t2 = aosoa.type(j);
125 auto const &ia_params = nonbonded_ias.get_ia_param(t1, t2);
126
127 // Determine which data needs to be loaded based on active algorithms
128#if defined(ESPRESSO_EXCLUSIONS) or defined(ESPRESSO_THOLE)
129 bool need_particle_pointers = false;
130#ifdef ESPRESSO_EXCLUSIONS
132#endif
133#ifdef ESPRESSO_THOLE
136#endif
137
138 Particle const *p1_ptr = nullptr;
139 Particle const *p2_ptr = nullptr;
141 p1_ptr = unique_particles.at(i);
143 }
144#endif
145
146 auto const tid = omp_get_thread_num();
147 double e_nb = 0.0;
148
149 if (dist <= ia_params.max_cut) {
150#ifdef ESPRESSO_EXCLUSIONS
151 bool skip = false;
153 skip = not do_nonbonded(*p1_ptr, *p2_ptr);
154 if (not skip)
155#endif
156 {
158
159 // Only call Thole energy kernel if active
160#ifdef ESPRESSO_THOLE
161 if (thole_active(ia_params, coulomb_u_kernel != nullptr)) {
164 }
165#endif
166 // Only call Gay-Berne energy kernel if active
167#ifdef ESPRESSO_GAY_BERNE
169 auto const dir1 = aosoa.get_vector_at(aosoa.director, i);
170 auto const dir2 = aosoa.get_vector_at(aosoa.director, j);
172 }
173#endif
174 }
175 }
176 // pick inter vs intra bin like Observable_stat::non_bonded_contribution
177 // does
178 auto const bin = (mol_id_view(i) == mol_id_view(j))
182
183#ifdef ESPRESSO_ELECTROSTATICS
184 if (coulomb_u_kernel != nullptr) {
185 auto const q1 = aosoa.charge(i), q2 = aosoa.charge(j);
186 if (q1 != 0. and q2 != 0.) {
187 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
188 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
189 double const e_c = (*coulomb_u_kernel)(pos1, pos2, q1 * q2, d, dist);
191 }
192 }
193#endif
194
195#ifdef ESPRESSO_DIPOLES
196 if (dipoles_u_kernel != nullptr) {
197 if (aosoa.dipm(i) != 0. and aosoa.dipm(j) != 0.) {
198 auto const dir1 = aosoa.get_vector_at(aosoa.director, i);
199 auto const dir2 = aosoa.get_vector_at(aosoa.director, j);
200 double const e_d = (*dipoles_u_kernel)(
201 aosoa.dipm(i) * dir1, aosoa.dipm(j) * dir2, d, dist, dist_sq);
203 }
204 }
205#endif
206 }
207};
208
210 Kokkos::View<double **, Kokkos::LayoutRight, Kokkos::HostSpace> const
211 &local_energy,
212 EnergyBinLayout const &layout, Observable_stat &obs,
213 BondedInteractionsMap const &bonded_ias, int n_types) {
214 auto const nthreads = local_energy.extent(0);
215 auto host =
216 Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, local_energy);
217
218 auto sum_bin = [&](std::size_t bin) {
219 double s = 0.;
220 for (std::size_t t = 0; t < nthreads; ++t)
221 s += host(t, bin);
222 return s;
223 };
224
225 for (int b = 0; b < int(layout.n_bonded); ++b)
226 obs.bonded_contribution(b)[0] += sum_bin(layout.bonded_idx(b));
227
228 for (int t1 = 0; t1 < n_types; ++t1)
229 for (int t2 = 0; t2 <= t1; ++t2)
230 obs.non_bonded_inter_contribution(t1, t2)[0] +=
231 sum_bin(layout.nb_inter_idx(t1, t2));
232
233 for (int t1 = 0; t1 < n_types; ++t1)
234 for (int t2 = 0; t2 <= t1; ++t2)
235 obs.non_bonded_intra_contribution(t1, t2)[0] +=
236 sum_bin(layout.nb_intra_idx(t1, t2));
237
238 obs.coulomb[0] += sum_bin(layout.coulomb_idx());
239 obs.dipolar[0] += sum_bin(layout.dipolar_idx());
240}
Vector implementation and trait types for boost qvm interoperability.
#define ESPRESSO_ATTR_ALWAYS_INLINE
container for bonded interactions.
ESPRESSO_ATTR_ALWAYS_INLINE Utils::Vector3< T > get_mi_vector(Utils::Vector3< T > const &a, Utils::Vector3< T > const &b) const
Get the minimum-image vector between two coordinates.
auto & get_ia_param(int i, int j)
Get interaction parameters between particle types i and j.
Observable for the pressure and energy.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
static void reduce_cabana_energy(Kokkos::View< double **, Kokkos::LayoutRight, Kokkos::HostSpace > const &local_energy, EnergyBinLayout const &layout, Observable_stat &obs, BondedInteractionsMap const &bonded_ias, int n_types)
Energy calculation.
double calc_central_radial_energy(IA_parameters const &ia_params, double const dist)
bool do_nonbonded(Particle const &p1, Particle const &p2)
Determine if the non-bonded interactions between p1 and p2 should be calculated.
double gb_pair_energy(Utils::Vector3d const &ui, Utils::Vector3d const &uj, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist)
Calculate Gay-Berne energy.
DEVICE_QUALIFIER T lower_triangular(T i, T j)
Linear index into a lower triangular matrix.
Definition index.hpp:86
STL namespace.
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION bool gay_berne_active(double dist, IA_parameters const &ia_params)
KOKKOS_INLINE_FUNCTION bool thole_active(IA_parameters const &ia_params, bool has_coulomb_kernel)
DEVICE_QUALIFIER bool has_exclusion(std::size_t i) const
PositionViewType position
DEVICE_QUALIFIER Utils::Vector< T, N > get_vector_at(Kokkos::View< T *[N], array_layout, Kokkos::HostSpace > const &view, std::size_t i) const
DirectorViewType director
Solver::ShortRangeEnergyKernel kernel_type
Solver::ShortRangeEnergyKernel kernel_type
std::size_t off_nb_inter
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION std::size_t nb_intra_idx(int t1, int t2) const
std::size_t n_types
EnergyBinLayout(std::size_t n_bonded_, std::size_t n_types_)
std::size_t off_bonded
std::size_t off_dipolar
KOKKOS_INLINE_FUNCTION std::size_t dipolar_idx() const
std::size_t off_nb_intra
KOKKOS_INLINE_FUNCTION std::size_t bonded_idx(int b) const
KOKKOS_INLINE_FUNCTION std::size_t coulomb_idx() const
std::size_t off_coulomb
std::size_t total
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION std::size_t nb_inter_idx(int t1, int t2) const
std::size_t n_bonded
CellStructure::AoSoA_pack const & aosoa
std::vector< Particle * > const & unique_particles
BondedInteractionsMap const & bonded_ias
Kokkos::View< double **, Kokkos::LayoutRight, memory_space > local_energy
InteractionsNonBonded const & nonbonded_ias
EnergyBinLayout layout
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t i, std::size_t j) const
Coulomb::Solver const & coulomb
Dipoles::ShortRangeEnergyKernel::kernel_type const * dipoles_u_kernel
Kokkos::View< int *, Kokkos::LayoutRight, memory_space > mol_id_view
BoxGeometry const & box_geo
Coulomb::ShortRangeEnergyKernel::kernel_type const * coulomb_u_kernel
double system_max_cutoff_sq
EnergyKernel(BondedInteractionsMap const &bonded_ias_, InteractionsNonBonded const &nonbonded_ias_, Coulomb::Solver const &coulomb_, Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_u_kernel_, Dipoles::ShortRangeEnergyKernel::kernel_type const *dipoles_u_kernel_, BoxGeometry const &box_geo_, std::vector< Particle * > const &unique_particles_, Kokkos::View< double **, Kokkos::LayoutRight, memory_space > const &local_energy_, EnergyBinLayout layout_, CellStructure::AoSoA_pack const &aosoa_, Kokkos::View< int *, memory_space > mol_id_view_, double system_max_cutoff_)
Kokkos::HostSpace memory_space
Struct holding all information for one particle.
Definition Particle.hpp:436
double thole_pair_energy(Particle const &p1, Particle const &p2, IA_parameters const &ia_params, Utils::Vector3d const &d, double dist, BondedInteractionsMap const &bonded_ias, Coulomb::Solver const &coulomb, Coulomb::ShortRangeEnergyKernel::kernel_type const *kernel)
Calculate Thole energy.
Definition thole.hpp:68