93 auto const &verlet_criterion,
95 auto const &intra_operator,
auto const &inter_operator) {
97 auto const distance_function = detail::MinimalImageDistance{box_geo};
103 auto intra_kernel = [&cells, &distance_function, &verlet_criterion,
104 &id_to_index, &intra_operator, max_id](
const int i) {
105 auto &local_particles = cells[i]->particles();
106 for (
auto it = local_particles.begin(); it != local_particles.end(); ++it) {
107 auto const &p1 = *it;
108 if (p1.id() <= max_id) {
109 auto const ii = id_to_index(p1.id());
112 for (
auto jt = std::next(it); jt != local_particles.end(); ++jt) {
113 if ((*jt).id() <= max_id) {
114 if (verlet_criterion(p1, *jt, distance_function(p1, *jt))) {
115 auto const jj = id_to_index((*jt).id());
117 intra_operator(ii, jj);
127 auto inter_kernel = [&cells, &distance_function, &verlet_criterion,
128 &id_to_index, &inter_operator, max_id](
const int i) {
129 auto &local_particles = cells[i]->particles();
130 for (
auto const &p1 : local_particles) {
131 if (p1.id() <= max_id) {
132 auto const ii = id_to_index(p1.id());
135 for (
auto &neighbor : cells[i]->neighbors().red()) {
136 for (
auto const &p2 : neighbor->particles()) {
137 if (p2.id() <= max_id) {
138 if (verlet_criterion(p1, p2, distance_function(p1, p2))) {
139 auto const jj = id_to_index(p2.id());
141 inter_operator(ii, jj);
152 Kokkos::parallel_for(
"intra", cells.size(), intra_kernel);
155 Kokkos::parallel_for(
"inter", cells.size(), inter_kernel);
161 double const pair_cutoff,
auto const integ_switch) {
162#ifdef ESPRESSO_CALIPER
163 CALI_CXX_MARK_FUNCTION;
165 using execution_space = Kokkos::DefaultExecutionSpace;
166 using policy_type = Kokkos::RangePolicy<execution_space>;
169 auto const n_part = unique_particles.size();
171 auto &aosoa = cell_structure.
get_aosoa();
179#ifdef ESPRESSO_CALIPER
180 CALI_MARK_BEGIN(
"AoSoA commit full");
184 int dihedral_count = 0;
185 kokkos_parallel_range_for<policy_type>(
186 "AoSoA write", std::size_t{0}, n_part,
187 [&unique_particles, &aosoa, &id_to_index, &cell_structure, &pair_count,
188 &angle_count, &dihedral_count](
int const index) {
189 auto const &p = *unique_particles.at(index);
191 id_to_index(p.id()) = index;
192 if (not p.is_ghost()) {
193 cell_structure.update_bond_storage(pair_count, angle_count,
198 auto &bs = cell_structure.bond_state();
199 auto &pair_bond_list = bs.pair_list;
200 Kokkos::parallel_for(
"resolve_pair_bond_indices", pair_count,
201 [&pair_bond_list, &id_to_index](
int idx) {
202 for (
int col = 0; col < 2; ++col) {
203 pair_bond_list(idx, col) =
204 id_to_index(pair_bond_list(idx, col));
207 auto &angle_bond_list = bs.angle_list;
208 Kokkos::parallel_for(
"resolve_angle_bond_indices", angle_count,
209 [&angle_bond_list, &id_to_index](
int idx) {
210 for (
int col = 0; col < 3; ++col) {
211 angle_bond_list(idx, col) =
212 id_to_index(angle_bond_list(idx, col));
215 auto &dihedral_bond_list = bs.dihedral_list;
216 Kokkos::parallel_for(
"resolve_dihedral_bond_indices", dihedral_count,
217 [&dihedral_bond_list, &id_to_index](
int idx) {
218 for (
int col = 0; col < 4; ++col) {
219 dihedral_bond_list(idx, col) =
220 id_to_index(dihedral_bond_list(idx, col));
224#ifdef ESPRESSO_CALIPER
225 CALI_MARK_END(
"AoSoA commit full");
232 cell_structure.use_verlet_list);
233#ifdef ESPRESSO_CALIPER
234 CALI_MARK_BEGIN(
"Verlet list creation");
236 cell_structure.rebuild_verlet_list_cabana(
237 [&](std::span<Cell *const> cells,
BoxGeometry const &box,
240 std::move(cells), box, verlet_criterion, id_to_index, max_id,
241 [&](
const int i,
const int j) {
245 [&](
const int i,
const int j) {
251 cell_structure.use_verlet_list =
false;
253 <<
"Verlet list overflow detected: neighbor count exceeded "
254 "max_counts. Falling back to the link cell algorithm. "
256 << Cabana::NeighborList<CellStructure::ListType>::maxNeighbor(
261#ifdef ESPRESSO_CALIPER
262 CALI_MARK_END(
"Verlet list creation");
268#ifdef ESPRESSO_CALIPER
269 CALI_MARK_BEGIN(
"AoSoA commit partial");
271 kokkos_parallel_range_for<policy_type>(
272 "AoSoA write", std::size_t{0}, n_part,
273 [&unique_particles, &aosoa](
int const index) {
274 auto const &p = *unique_particles.at(index);
278#ifdef ESPRESSO_CALIPER
279 CALI_MARK_END(
"AoSoA commit partial");
287 using execution_space = Kokkos::DefaultExecutionSpace;
288 using policy_type = Kokkos::RangePolicy<execution_space>;
290 auto const n_part = unique_particles.size();
291 auto &aosoa = cell_structure.
get_aosoa();
293 kokkos_parallel_range_for<policy_type>(
294 "Views update charges", std::size_t{0}, n_part,
295 [&unique_particles, &aosoa](std::size_t
const index) {
296 aosoa.charge(index) = unique_particles.at(index)->q();
302 auto const &angle_bonds_kernel,
303 auto const &dihedral_bonds_kernel,
304 auto const &nonbonded_kernel,
306 double bond_cutoff,
auto const &verlet_criterion,
307 auto const integ_switch) {
308 using execution_space = Kokkos::DefaultExecutionSpace;
311 if (bond_cutoff >= 0.) {
312#ifdef ESPRESSO_CALIPER
313 CALI_MARK_BEGIN(
"cabana_bond_loop");
317 auto const n_dihedral_bonds =
319 if (n_pair_bonds > 0) {
320 Kokkos::parallel_for(
321 "for_each_local_pair_bonds", n_pair_bonds, pair_bonds_kernel);
324 if (n_angle_bonds > 0) {
325 Kokkos::parallel_for(
326 "for_each_local_angle_bonds", n_angle_bonds, angle_bonds_kernel);
329 if (n_dihedral_bonds > 0) {
330 Kokkos::parallel_for(
331 "for_each_local_dihedral_bonds", n_dihedral_bonds,
332 dihedral_bonds_kernel);
335#ifdef ESPRESSO_CALIPER
336 CALI_MARK_END(
"cabana_bond_loop");
341 if (pair_cutoff > 0.) {
342#ifdef ESPRESSO_CALIPER
343 CALI_MARK_BEGIN(
"cabana_pair_loop");
348 Kokkos::RangePolicy<execution_space> policy(
350 Cabana::neighbor_parallel_for(policy, nonbonded_kernel, verlet_list,
351 Cabana::FirstNeighborsTag(),
352 Cabana::SerialOpTag());
355 [&](std::span<Cell *const> cells,
BoxGeometry const &box) {
357 std::move(cells), box, verlet_criterion,
360 [&](
const int i,
const int j) {
362 nonbonded_kernel(i, j);
364 [&](
const int i,
const int j) {
366 nonbonded_kernel(i, j);
371#ifdef ESPRESSO_CALIPER
372 CALI_MARK_END(
"cabana_pair_loop");
ESPRESSO_ATTR_ALWAYS_INLINE void link_cell_kokkos(std::span< Cell *const > cells, BoxGeometry const &box_geo, auto const &verlet_criterion, Kokkos::View< int * > const &id_to_index, int const max_id, auto const &intra_operator, auto const &inter_operator)
void cabana_short_range(auto const &pair_bonds_kernel, auto const &angle_bonds_kernel, auto const &dihedral_bonds_kernel, auto const &nonbonded_kernel, CellStructure &cell_structure, double pair_cutoff, double bond_cutoff, auto const &verlet_criterion, auto const integ_switch)
Struct holding all information for one particle.
auto const & mass() const
Utils::compact_vector< int > & exclusions()
auto const & quat() const
auto const & image_box() const
auto const & type() const
auto const & dipm() const