ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
bond_forces_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"
26#include "forces_inline.hpp"
27
28#include <utils/Vector.hpp>
29
30#include <Kokkos_Core.hpp>
31#include <Kokkos_ScatterView.hpp>
32
33#include <cstddef>
34#include <optional>
35#include <variant>
36
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_force = data.local_force.access();
66 auto const &aosoa = data.aosoa;
67 auto &bond_breakage = data.bond_breakage;
68#ifdef ESPRESSO_NPT
69 auto local_virial = data.local_virial.access();
70#endif
71 auto const has_breakage_specs = data.has_breakage_specs;
72 auto const bond_id = bond_ids(idx);
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 dx =
79 box_geo.get_mi_vector(aosoa.get_vector_at(aosoa.position, i),
80 aosoa.get_vector_at(aosoa.position, j));
81 // Consider for bond breakage
82 if (has_breakage_specs &&
83 bond_breakage.check_and_handle_breakage(
84 aosoa.id(i), {{aosoa.id(j), std::nullopt}}, bond_id, dx.norm())) {
85 return;
86 }
87
88 if (auto const *iap = std::get_if<ThermalizedBond>(&iaparams)) {
89 auto const result = iap->forces(
91 aosoa.mass(i), aosoa.mass(j),
92#else
93 1.0, 1.0,
94#endif
95 aosoa.get_vector_at(aosoa.velocity, i),
96 aosoa.get_vector_at(aosoa.velocity, j), aosoa.id(i), aosoa.id(j), dx);
97 if (result) {
98 auto const &forces = result.value();
99
100 local_force(i, 0) += std::get<0>(forces)[0];
101 local_force(i, 1) += std::get<0>(forces)[1];
102 local_force(i, 2) += std::get<0>(forces)[2];
103 local_force(j, 0) += std::get<1>(forces)[0];
104 local_force(j, 1) += std::get<1>(forces)[1];
105 local_force(j, 2) += std::get<1>(forces)[2];
106 } else {
107 auto partner_id = aosoa.id(j);
108 bond_broken_error(aosoa.id(i), {&partner_id, 1});
109 }
110 return;
111 }
112
113 auto const result =
116 aosoa.charge(i) * aosoa.charge(j), coulomb_kernel
117#else
118 0.0, nullptr
119#endif
120 );
121
122 if (result) {
123 auto const f = result.value();
124 local_force(i, 0) += f[0];
125 local_force(i, 1) += f[1];
126 local_force(i, 2) += f[2];
127 local_force(j, 0) -= f[0];
128 local_force(j, 1) -= f[1];
129 local_force(j, 2) -= f[2];
130#ifdef ESPRESSO_NPT
131 auto const virial = hadamard_product(f, dx);
132 local_virial(0) += virial[0];
133 local_virial(1) += virial[1];
134 local_virial(2) += virial[2];
135#endif
136 } else {
137 auto partner_id = aosoa.id(j);
138 bond_broken_error(aosoa.id(i), {&partner_id, 1});
139 }
140 }
141};
142
147
153
154 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t idx) const {
155 auto const &bonded_ias = data.bonded_ias;
156 auto const &box_geo = data.box_geo;
157 auto local_force = data.local_force.access();
158 auto const &aosoa = data.aosoa;
159 auto &bond_breakage = data.bond_breakage;
160 auto const has_breakage_specs = data.has_breakage_specs;
161 auto const bond_id = bond_ids(idx);
162
163 auto const i = bond_list(idx, 0);
164 auto const j = bond_list(idx, 1);
165 auto const k = bond_list(idx, 2);
166 auto const &iaparams = *bonded_ias.at(bond_id);
167
168 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
169 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
170 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
171 auto const vec1 = box_geo.get_mi_vector(pos2, pos1);
172 auto const vec2 = box_geo.get_mi_vector(pos3, pos1);
173
174 // Consider for bond breakage
175 if (has_breakage_specs &&
176 bond_breakage.check_and_handle_breakage(
177 aosoa.id(i), {{aosoa.id(j), aosoa.id(k)}}, bond_id,
178 box_geo.get_mi_vector(pos2, pos3).norm())) {
179 return;
180 }
181 if (std::get_if<OifGlobalForcesBond>(&iaparams)) {
182 return;
183 }
184
185 auto const result = calc_bonded_three_body_force(iaparams, vec1, vec2);
186
187 if (result) {
188 auto const &forces = result.value();
189
190 local_force(i, 0) += std::get<0>(forces)[0];
191 local_force(i, 1) += std::get<0>(forces)[1];
192 local_force(i, 2) += std::get<0>(forces)[2];
193 local_force(j, 0) += std::get<1>(forces)[0];
194 local_force(j, 1) += std::get<1>(forces)[1];
195 local_force(j, 2) += std::get<1>(forces)[2];
196 local_force(k, 0) += std::get<2>(forces)[0];
197 local_force(k, 1) += std::get<2>(forces)[1];
198 local_force(k, 2) += std::get<2>(forces)[2];
199 } else {
200 std::array<int, 2> pids = {aosoa.id(j), aosoa.id(k)};
201 bond_broken_error(aosoa.id(i), {pids.data(), 2});
202 }
203 }
204};
205
210
216
217 ESPRESSO_ATTR_ALWAYS_INLINE inline void operator()(std::size_t idx) const {
218 auto const &bonded_ias = data.bonded_ias;
219 auto const &box_geo = data.box_geo;
220 auto local_force = data.local_force.access();
221 auto const &aosoa = data.aosoa;
222 auto const bond_id = bond_ids(idx);
223
224 auto const i = bond_list(idx, 0);
225 auto const j = bond_list(idx, 1);
226 auto const k = bond_list(idx, 2);
227 auto const m = bond_list(idx, 3);
228 auto const &iaparams = *bonded_ias.at(bond_id);
229
230 auto const pos1 = aosoa.get_vector_at(aosoa.position, i);
231 auto const pos2 = aosoa.get_vector_at(aosoa.position, j);
232 auto const pos3 = aosoa.get_vector_at(aosoa.position, k);
233 auto const pos4 = aosoa.get_vector_at(aosoa.position, m);
234 auto const vel1 = aosoa.get_vector_at(aosoa.velocity, i);
235 auto const vel3 = aosoa.get_vector_at(aosoa.velocity, k);
236 auto const image1 = aosoa.get_vector_at(aosoa.image, i);
237
238 auto const result = calc_bonded_four_body_force(
239 iaparams, box_geo, pos1, pos2, pos3, pos4, vel1, vel3, image1);
240
241 if (result) {
242 auto const &forces = result.value();
243
244 local_force(i, 0) += std::get<0>(forces)[0];
245 local_force(i, 1) += std::get<0>(forces)[1];
246 local_force(i, 2) += std::get<0>(forces)[2];
247 local_force(j, 0) += std::get<1>(forces)[0];
248 local_force(j, 1) += std::get<1>(forces)[1];
249 local_force(j, 2) += std::get<1>(forces)[2];
250 local_force(k, 0) += std::get<2>(forces)[0];
251 local_force(k, 1) += std::get<2>(forces)[1];
252 local_force(k, 2) += std::get<2>(forces)[2];
253 local_force(m, 0) += std::get<3>(forces)[0];
254 local_force(m, 1) += std::get<3>(forces)[1];
255 local_force(m, 2) += std::get<3>(forces)[2];
256 } else {
257 std::array<int, 3> pids = {aosoa.id(j), aosoa.id(k), aosoa.id(m)};
258 bond_broken_error(aosoa.id(i), {pids.data(), 3});
259 }
260 }
261};
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.
Kokkos::Experimental::ScatterView< double *[3], Kokkos::LayoutRight, memory_space > ScatterForce
Kokkos::Experimental::ScatterView< double[3], Kokkos::LayoutRight, memory_space > ScatterVirial
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
Force calculation.
ESPRESSO_ATTR_ALWAYS_INLINE std::optional< Utils::Vector3d > calc_bond_pair_force(Bonded_IA_Parameters const &iaparams, Utils::Vector3d const &dx, double const q1q2, Coulomb::ShortRangeForceKernel::kernel_type const *kernel)
Compute the bonded interaction force between particle pairs.
ESPRESSO_ATTR_ALWAYS_INLINE std::optional< std::tuple< Utils::Vector3d, Utils::Vector3d, Utils::Vector3d, Utils::Vector3d > > calc_bonded_four_body_force(Bonded_IA_Parameters const &iaparams, BoxGeometry const &box_geo, Utils::Vector3d const &pos1, Utils::Vector3d const &pos2, Utils::Vector3d const &pos3, Utils::Vector3d const &pos4, Utils::Vector3d const &vel1, Utils::Vector3d const &vel3, Utils::Vector3i const &image1)
ESPRESSO_ATTR_ALWAYS_INLINE std::optional< std::tuple< Utils::Vector3d, Utils::Vector3d, Utils::Vector3d > > calc_bonded_three_body_force(Bonded_IA_Parameters const &iaparams, Utils::Vector3d const &vec1, Utils::Vector3d const &vec2)
auto hadamard_product(Vector< T, N > const &a, Vector< U, N > const &b)
Definition Vector.hpp:385
STL namespace.
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
LocalBondState::AngleBondIDType bond_ids
AngleBondsKernel(BondsKernelData data_, LocalBondState::AngleBondlistType bond_list_, LocalBondState::AngleBondIDType bond_ids_)
LocalBondState::AngleBondlistType bond_list
CellStructure::AoSoA_pack const & aosoa
bool const has_breakage_specs
BondBreakage::BondBreakage & bond_breakage
CellStructure::ScatterForce local_force
BondedInteractionsMap const & bonded_ias
BoxGeometry const & box_geo
CellStructure::ScatterVirial local_virial
Solver::ShortRangeForceKernel kernel_type
DihedralBondsKernel(BondsKernelData data_, LocalBondState::DihedralBondlistType bond_list_, LocalBondState::DihedralBondIDType bond_ids_)
LocalBondState::DihedralBondIDType bond_ids
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
LocalBondState::DihedralBondlistType bond_list
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
PairBondsKernel(BondsKernelData data_, LocalBondState::PairBondlistType bond_list_, LocalBondState::PairBondIDType bond_ids_, Coulomb::ShortRangeForceKernel::kernel_type const *coulomb_kernel_)
ESPRESSO_ATTR_ALWAYS_INLINE void operator()(std::size_t idx) const
LocalBondState::PairBondIDType bond_ids
Coulomb::ShortRangeForceKernel::kernel_type const *const coulomb_kernel
LocalBondState::PairBondlistType bond_list
BondsKernelData data