28#include "constraints/Constraints.hpp"
32#include "system/System.hpp"
47 auto obs_energy_ptr = std::make_shared<Observable_stat>(
48 1ul,
static_cast<std::size_t
>(bonded_ias->get_next_key()),
49 nonbonded_ias->get_max_seen_particle_type());
51 if (long_range_interactions_sanity_checks()) {
52 return obs_energy_ptr;
55 auto &obs_energy = *obs_energy_ptr;
56#if defined(ESPRESSO_CUDA) and \
57 (defined(ESPRESSO_ELECTROSTATICS) or defined(ESPRESSO_DIPOLES))
58 gpu.clear_energy_on_device();
63 auto const local_parts = cell_structure->local_particles();
65 for (
auto const &p : local_parts) {
70 auto const coulomb_kernel = coulomb.pair_energy_kernel();
71 auto const dipoles_kernel = dipoles.pair_energy_kernel();
74 [
this, coulomb_kernel_ptr =
get_ptr(coulomb_kernel), &obs_energy](
75 Particle const &p1,
int bond_id, std::span<Particle *> partners) {
76 auto const &iaparams = *bonded_ias->at(bond_id);
80 obs_energy.bonded_contribution(bond_id)[0] += result.value();
85 [coulomb_kernel_ptr =
get_ptr(coulomb_kernel),
86 dipoles_kernel_ptr =
get_ptr(dipoles_kernel),
this,
88 auto const &ia_params =
89 nonbonded_ias->get_ia_param(p1.
type(), p2.type());
91 p1, p2, d.vec21, sqrt(d.dist2), d.dist2, ia_params, *bonded_ias,
92 coulomb, coulomb_kernel_ptr, dipoles_kernel_ptr, obs_energy);
94 *cell_structure, maximal_cutoff(), bonded_ias->maximal_cutoff());
96#ifdef ESPRESSO_ELECTROSTATICS
98 obs_energy.coulomb[1] = coulomb.calc_energy_long_range();
101#ifdef ESPRESSO_DIPOLES
103 obs_energy.dipolar[1] = dipoles.calc_energy_long_range();
106 constraints->add_energy(local_parts, get_sim_time(), obs_energy);
108#if defined(ESPRESSO_CUDA) and \
109 (defined(ESPRESSO_ELECTROSTATICS) or defined(ESPRESSO_DIPOLES))
110 auto const energy_host = gpu.copy_energy_to_host();
111 if (!obs_energy.coulomb.empty())
112 obs_energy.coulomb[1] +=
static_cast<double>(energy_host.coulomb);
113 if (!obs_energy.dipolar.empty())
114 obs_energy.dipolar[1] +=
static_cast<double>(energy_host.dipolar);
117 obs_energy.mpi_reduce();
118 return obs_energy_ptr;
123 if (cell_structure->get_resort_particles()) {
124 cell_structure->update_ghosts_and_resort_particle(get_global_ghost_flags());
128 if (
auto const p = cell_structure->get_local_particle(pid)) {
129 auto const coulomb_kernel = coulomb.pair_energy_kernel();
130 auto kernel = [coulomb_kernel_ptr =
get_ptr(coulomb_kernel), &ret,
133#ifdef ESPRESSO_EXCLUSIONS
137 auto const &ia_params = nonbonded_ias->get_ia_param(p.type(), p1.type());
141 *bonded_ias, coulomb, coulomb_kernel_ptr);
143 cell_structure->run_on_particle_short_range_neighbors(*p, kernel);
149 std::vector<int> partners) {
150 if (cell_structure->get_resort_particles()) {
151 cell_structure->update_ghosts_and_resort_particle(get_global_ghost_flags());
153 Particle const *p = cell_structure->get_local_particle(pid);
156 auto const &iaparams = *bonded_ias->at(bond_id);
158 auto resolved_partners = cell_structure->resolve_bond_partners(partners);
159 auto const coulomb_kernel = coulomb.pair_energy_kernel();
162 std::span(resolved_partners.data(), resolved_partners.size()), *box_geo,
void bond_broken_error(int id, std::span< const int > partner_ids)
double particle_short_range_energy_contribution(int pid)
Compute the short-range energy of a particle.
std::optional< double > particle_bond_energy(int pid, int bond_id, std::vector< int > partners)
Compute the energy of a given bond which has to exist on the given particle.
std::shared_ptr< Observable_stat > calculate_energy()
Calculate the total energy.
const T * get_ptr(std::optional< T > const &opt)
void add_non_bonded_pair_energy(Particle const &p1, Particle const &p2, Utils::Vector3d const &d, double const dist, double const dist2, IA_parameters const &ia_params, BondedInteractionsMap const &bonded_ias, Coulomb::Solver const &coulomb, Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_kernel, Dipoles::ShortRangeEnergyKernel::kernel_type const *dipoles_kernel, Observable_stat &obs_energy)
Add non-bonded and short-range Coulomb energies between a pair of particles to the energy observable.
std::optional< double > calc_bonded_energy(Bonded_IA_Parameters const &iaparams, Particle const &p1, std::span< Particle * > partners, BoxGeometry const &box_geo, Coulomb::ShortRangeEnergyKernel::kernel_type const *kernel)
double translational_kinetic_energy(Particle const &p)
Calculate kinetic energies from translation for one particle.
double rotational_kinetic_energy(Particle const &p)
Calculate kinetic energies from rotation for one particle.
double calc_non_bonded_pair_energy(Particle const &p1, Particle const &p2, IA_parameters const &ia_params, Utils::Vector3d const &d, double const dist, BondedInteractionsMap const &bonded_ias, Coulomb::Solver const &coulomb, Coulomb::ShortRangeEnergyKernel::kernel_type const *coulomb_kernel)
Calculate non-bonded energies between a pair of particles.
bool do_nonbonded(Particle const &p1, Particle const &p2)
Determine if the non-bonded interactions between p1 and p2 should be calculated.
Various procedures concerning interactions between particles.
void short_range_loop(BondKernel bond_kernel, PairKernel pair_kernel, CellStructure &cell_structure, double pair_cutoff, double bond_cutoff, VerletCriterion const &verlet_criterion={})
Exception indicating that a particle id could not be resolved.
Distance vector and length handed to pair kernels.
Struct holding all information for one particle.
auto const & type() const