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
47
53
57 Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_u_kernel_)
58 : data(std::move(data_)), bond_list(std::move(bond_list_)),
59 bond_ids(std::move(bond_ids_)), coulomb_u_kernel(coulomb_u_kernel_) {}
60
61 ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION void
62 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,
84#ifdef ESPRESSO_ELECTROSTATICS
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
108 : data(std::move(data_)), bond_list(std::move(bond_list_)),
109 bond_ids(std::move(bond_ids_)) {}
110
111 ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION void
112 operator()(std::size_t idx) const {
113 auto const &bonded_ias = data.bonded_ias;
114 auto const &box_geo = data.box_geo;
115 auto &local_energy = data.local_energy;
116 auto const &layout = data.layout;
117 auto const &aosoa = data.aosoa;
118 auto const bond_id = bond_ids(idx);
119
120 // TODO: omp_get_thread_num() is only available for the OpenMP backend.
121 // This should be updated when using other Kokkos backends.
122 auto const thread_id = omp_get_thread_num();
123
124 auto const i = bond_list(idx, 0);
125 auto const j = bond_list(idx, 1);
126 auto const k = bond_list(idx, 2);
127 auto const &iaparams = *bonded_ias.at(bond_id);
128
129 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
130 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
131 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
132 auto const vec1 = box_geo.get_mi_vector(pos2, pos1);
133 auto const vec2 = box_geo.get_mi_vector(pos3, pos1);
134
135 std::optional<double> energy =
136 calc_angle_bonded_energy(iaparams, vec1, vec2);
137
138 if (energy) {
139 local_energy(thread_id, layout.bonded_idx(bond_id)) += energy.value();
140 } else {
141 std::array<int, 2> pids = {aosoa.id(j), aosoa.id(k)};
142 bond_broken_error(aosoa.id(i), {pids.data(), 2});
143 }
144 }
145};
146
151
155 : data(std::move(data_)), bond_list(std::move(bond_list_)),
156 bond_ids(std::move(bond_ids_)) {}
157
158 ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION void
159 operator()(std::size_t idx) const {
160 auto const &bonded_ias = data.bonded_ias;
161 auto const &box_geo = data.box_geo;
162 auto &local_energy = data.local_energy;
163 auto const &layout = data.layout;
164 auto const &aosoa = data.aosoa;
165 auto const bond_id = bond_ids(idx);
166
167 // TODO: omp_get_thread_num() is only available for the OpenMP backend.
168 // This should be updated when using other Kokkos backends.
169 auto const thread_id = omp_get_thread_num();
170
171 auto const i = bond_list(idx, 0);
172 auto const j = bond_list(idx, 1);
173 auto const k = bond_list(idx, 2);
174 auto const m = bond_list(idx, 3);
175 auto const &iaparams = *bonded_ias.at(bond_id);
176
177 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
178 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
179 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
180 auto const pos4 = aosoa.get_vector_at(aosoa.position, m);
181 auto const v12 = box_geo.get_mi_vector(pos1, pos2);
182 auto const v23 = box_geo.get_mi_vector(pos3, pos1);
183 auto const v34 = box_geo.get_mi_vector(pos4, pos3);
184
185 std::optional<double> energy =
186 calc_dihedral_bonded_energy(iaparams, v12, v23, v34);
187
188 if (energy) {
189 local_energy(thread_id, layout.bonded_idx(bond_id)) += energy.value();
190 } else {
191 std::array<int, 3> pids = {aosoa.id(j), aosoa.id(k), aosoa.id(m)};
192 bond_broken_error(aosoa.id(i), {pids.data(), 3});
193 }
194 }
195};
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.
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 KOKKOS_INLINE_FUNCTION 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
Kokkos::View< double **, Kokkos::LayoutRight > local_energy
BoxGeometry const & box_geo
CellStructure::AoSoA_pack const & aosoa
Solver::ShortRangeEnergyKernel kernel_type
DihedralBondsEnergyKernel(BondsEnergyKernelData data_, LocalBondState::DihedralBondlistType bond_list_, LocalBondState::DihedralBondIDType bond_ids_)
LocalBondState::DihedralBondlistType bond_list
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION void operator()(std::size_t idx) const
LocalBondState::DihedralBondIDType bond_ids
ESPRESSO_ATTR_ALWAYS_INLINE KOKKOS_INLINE_FUNCTION void operator()(std::size_t idx) const
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_)
LocalBondState::PairBondlistType bond_list