66 if (not m_obs_energy) {
68 m_obs_energy = std::make_shared<EnergyObservable>();
69 m_obs_energy->observable = std::make_unique<Observable_stat>(1ul, 0ul, 0);
71 decltype(m_obs_energy->local)(
"local_energy", n_threads, 1ul);
74 auto &local_energy = m_obs_energy->local;
75 auto &obs_energy = *m_obs_energy->observable;
76 obs_energy.reset(
static_cast<std::size_t
>(bonded_ias->get_next_key()),
77 nonbonded_ias->get_max_seen_particle_type());
79 if (long_range_interactions_sanity_checks()) {
83#if defined(ESPRESSO_CUDA) and \
84 (defined(ESPRESSO_ELECTROSTATICS) or defined(ESPRESSO_DIPOLES))
85 gpu->clear_energy_on_device();
90 auto const local_parts = cell_structure->local_particles();
92 for (
auto const &p : local_parts) {
97 auto const coulomb_kernel = coulomb.pair_energy_kernel();
98 auto const dipoles_kernel = dipoles.pair_energy_kernel();
100#ifdef ESPRESSO_CALIPER
105 auto const make_verlet_criterion = [&] {
107 cell_structure->get_verlet_skin(),
108 get_interaction_range(),
116 static_cast<std::size_t
>(bonded_ias->get_next_key()),
117 std::size_t(nonbonded_ias->get_max_seen_particle_type() + 1)};
119 using exec = Kokkos::DefaultHostExecutionSpace;
120 if (local_energy.extent(1) != layout.total) {
121 Kokkos::realloc(Kokkos::WithoutInitializing, local_energy,
122 exec{}.concurrency(), layout.total);
126 auto const &unique_particles = cell_structure->get_unique_particles();
127 auto const n_particles = unique_particles.size();
128 Kokkos::View<int *, Kokkos::LayoutRight, exec> mol_id(
"mol_id", n_particles);
129 for (std::size_t i = 0; i < n_particles; ++i) {
130 mol_id(i) = unique_particles[i]->mol_id();
140 cell_structure->get_unique_particles(),
143 cell_structure->get_aosoa(),
148 auto &bs = cell_structure->bond_state();
150 layout, cell_structure->get_aosoa()};
159 pair_e_kernel, *cell_structure, get_interaction_range(),
160 bonded_ias->maximal_cutoff(), make_verlet_criterion,
161 propagation->integ_switch);
164 nonbonded_ias->get_max_seen_particle_type() + 1);
165#ifdef ESPRESSO_CALIPER
169#ifdef ESPRESSO_ELECTROSTATICS
171 obs_energy.coulomb[1] = coulomb.calc_energy_long_range();
174#ifdef ESPRESSO_DIPOLES
176 obs_energy.dipolar[1] = dipoles.calc_energy_long_range();
179 constraints->add_energy(local_parts, get_sim_time(), obs_energy);
181#if defined(ESPRESSO_CUDA) and \
182 (defined(ESPRESSO_ELECTROSTATICS) or defined(ESPRESSO_DIPOLES))
183 auto const energy_host = gpu->copy_energy_to_host();
184 if (!obs_energy.coulomb.empty())
185 obs_energy.coulomb[1] +=
static_cast<double>(energy_host.coulomb);
186 if (!obs_energy.dipolar.empty())
187 obs_energy.dipolar[1] +=
static_cast<double>(energy_host.dipolar);
190 obs_energy.mpi_reduce();
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.
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 &make_verlet_criterion, auto const integ_switch, ShortRangeVerletPairLoop const &verlet_pair_loop={})
Struct holding all information for one particle.
constexpr auto const & id() const
constexpr bool is_ghost() const