ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
bond_energy_kokkos.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 "bond_error.hpp"
27#include "energy_cabana.hpp"
28#include "energy_inline.hpp"
29
30#include <utils/Vector.hpp>
31
32#include <Kokkos_Core.hpp>
33
34#include <omp.h>
35
36#include <cstddef>
37#include <optional>
38#include <variant>
39
41 using execution_space = Kokkos::HostSpace;
44 Kokkos::View<double **, Kokkos::LayoutRight, execution_space> local_energy;
47};
48
54
61
62 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t idx) const {
63 auto const &bonded_ias = data.bonded_ias;
64 auto const &box_geo = data.box_geo;
65 auto &local_energy = data.local_energy;
66 auto const &layout = data.layout;
67 auto const &aosoa = data.aosoa;
68 auto const bond_id = bond_ids(idx);
69
70 // TODO: omp_get_thread_num() is only available for the OpenMP backend.
71 // This should be updated when using other Kokkos backends.
72 auto const thread_id = omp_get_thread_num();
73
74 auto const i = bond_list(idx, 0);
75 auto const j = bond_list(idx, 1);
76 auto const &iaparams = *bonded_ias.at(bond_id);
77
78 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
79 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
80 auto const dx = box_geo.get_mi_vector(pos1, pos2);
81
82 std::optional<double> energy = calc_pair_bonded_energy(
83 iaparams, dx, pos1, pos2,
85 aosoa.charge(i) * aosoa.charge(j), coulomb_u_kernel
86#else
87 0.0, nullptr
88#endif
89 );
90
91 if (energy) {
92 local_energy(thread_id, layout.bonded_idx(bond_id)) += energy.value();
93 } else {
94 auto partner_id = aosoa.id(j);
95 bond_broken_error(aosoa.id(i), {&partner_id, 1});
96 }
97 }
98};
99
104
110
111 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t idx) const {
112 auto const &bonded_ias = data.bonded_ias;
113 auto const &box_geo = data.box_geo;
114 auto &local_energy = data.local_energy;
115 auto const &layout = data.layout;
116 auto const &aosoa = data.aosoa;
117 auto const bond_id = bond_ids(idx);
118
119 // TODO: omp_get_thread_num() is only available for the OpenMP backend.
120 // This should be updated when using other Kokkos backends.
121 auto const thread_id = omp_get_thread_num();
122
123 auto const i = bond_list(idx, 0);
124 auto const j = bond_list(idx, 1);
125 auto const k = bond_list(idx, 2);
126 auto const &iaparams = *bonded_ias.at(bond_id);
127
128 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
129 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
130 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
131 auto const vec1 = box_geo.get_mi_vector(pos2, pos1);
132 auto const vec2 = box_geo.get_mi_vector(pos3, pos1);
133
134 std::optional<double> energy =
136
137 if (energy) {
138 local_energy(thread_id, layout.bonded_idx(bond_id)) += energy.value();
139 } else {
140 std::array<int, 2> pids = {aosoa.id(j), aosoa.id(k)};
141 bond_broken_error(aosoa.id(i), {pids.data(), 2});
142 }
143 }
144};
145
150
156
157 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t idx) const {
158 auto const &bonded_ias = data.bonded_ias;
159 auto const &box_geo = data.box_geo;
160 auto &local_energy = data.local_energy;
161 auto const &layout = data.layout;
162 auto const &aosoa = data.aosoa;
163 auto const bond_id = bond_ids(idx);
164
165 // TODO: omp_get_thread_num() is only available for the OpenMP backend.
166 // This should be updated when using other Kokkos backends.
167 auto const thread_id = omp_get_thread_num();
168
169 auto const i = bond_list(idx, 0);
170 auto const j = bond_list(idx, 1);
171 auto const k = bond_list(idx, 2);
172 auto const m = bond_list(idx, 3);
173 auto const &iaparams = *bonded_ias.at(bond_id);
174
175 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
176 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
177 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
178 auto const pos4 = aosoa.get_vector_at(aosoa.position, m);
179 auto const v12 = box_geo.get_mi_vector(pos1, pos2);
180 auto const v23 = box_geo.get_mi_vector(pos3, pos1);
181 auto const v34 = box_geo.get_mi_vector(pos4, pos3);
182
183 std::optional<double> energy =
185
186 if (energy) {
187 local_energy(thread_id, layout.bonded_idx(bond_id)) += energy.value();
188 } else {
189 std::array<int, 3> pids = {aosoa.id(j), aosoa.id(k), aosoa.id(m)};
190 bond_broken_error(aosoa.id(i), {pids.data(), 3});
191 }
192 }
193};
Vector implementation and trait types for boost qvm interoperability.
#define ESPRESSO_ATTR_ALWAYS_INLINE
void bond_broken_error(int id, std::span< const int > partner_ids)
container for bonded interactions.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
Energy calculation.
std::optional< double > calc_dihedral_bonded_energy(Bonded_IA_Parameters const &iaparams, Utils::Vector3d const &v12, Utils::Vector3d const &v23, Utils::Vector3d const &v34)
std::optional< double > calc_pair_bonded_energy(Bonded_IA_Parameters const &iaparams, Utils::Vector3d const &dx, Utils::Vector3d const &pos1, Utils::Vector3d const &pos2, double q1q2, Coulomb::ShortRangeEnergyKernel::kernel_type const *kernel)
std::optional< double > calc_angle_bonded_energy(Bonded_IA_Parameters const &iaparams, Utils::Vector3d const &vec1, Utils::Vector3d const &vec2)
STL namespace.
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
BondsEnergyKernelData data
AngleBondsEnergyKernel(BondsEnergyKernelData data_, LocalBondState::AngleBondlistType bond_list_, LocalBondState::AngleBondIDType bond_ids_)
LocalBondState::AngleBondlistType bond_list
LocalBondState::AngleBondIDType bond_ids
BondedInteractionsMap const & bonded_ias
BoxGeometry const & box_geo
Kokkos::View< double **, Kokkos::LayoutRight, execution_space > local_energy
CellStructure::AoSoA_pack const & aosoa
Kokkos::HostSpace execution_space
Solver::ShortRangeEnergyKernel kernel_type
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
DihedralBondsEnergyKernel(BondsEnergyKernelData data_, LocalBondState::DihedralBondlistType bond_list_, LocalBondState::DihedralBondIDType bond_ids_)
LocalBondState::DihedralBondlistType bond_list
LocalBondState::DihedralBondIDType bond_ids
Kokkos::View< int *, Kokkos::LayoutRight, execution_space > AngleBondIDType
Kokkos::View< int *[3], Kokkos::LayoutRight, execution_space > AngleBondlistType
Kokkos::View< int *[2], Kokkos::LayoutRight, execution_space > PairBondlistType
Kokkos::View< int *, Kokkos::LayoutRight, execution_space > DihedralBondIDType
Kokkos::View< int *[4], Kokkos::LayoutRight, execution_space > DihedralBondlistType
Kokkos::View< int *, Kokkos::LayoutRight, execution_space > PairBondIDType
Coulomb::ShortRangeEnergyKernel::kernel_type const *const coulomb_u_kernel
BondsEnergyKernelData data
LocalBondState::PairBondIDType bond_ids
PairBondsEnergyKernel(BondsEnergyKernelData data_, LocalBondState::PairBondlistType bond_list_, LocalBondState::PairBondIDType bond_ids_, Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_u_kernel_)
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
LocalBondState::PairBondlistType bond_list