62 if (not m_obs_pressure) {
64 m_obs_pressure = std::make_shared<PressureObservable>();
65 m_obs_pressure->observable = std::make_unique<Observable_stat>(9ul, 0ul, 0);
66 m_obs_pressure->local =
67 decltype(m_obs_pressure->local)(
"local_pressure", n_threads, 9ul);
70 auto &local_pressure = m_obs_pressure->local;
71 auto &obs_pressure = *m_obs_pressure->observable;
72 obs_pressure.reset(
static_cast<std::size_t
>(bonded_ias->get_next_key()),
73 nonbonded_ias->get_max_seen_particle_type());
75 if (long_range_interactions_sanity_checks()) {
81 auto const volume = box_geo->volume();
84 auto const kinetic = reduce_over_local_particles<Utils::Matrix<double, 3, 3>>(
90 [](
auto &a,
auto const &b) { a += b; });
91 std::ranges::copy(
Utils::flatten(kinetic), obs_pressure.kinetic_lin.begin());
93 auto const coulomb_force_kernel = coulomb.pair_force_kernel();
94 auto const coulomb_pressure_kernel = coulomb.pair_pressure_kernel();
95 auto const dipoles_pressure_kernel = dipoles.pair_pressure_kernel();
99 auto const make_verlet_criterion = [&] {
101 cell_structure->get_verlet_skin(),
102 get_interaction_range(),
110 static_cast<std::size_t
>(bonded_ias->get_next_key()),
111 std::size_t(nonbonded_ias->get_max_seen_particle_type() + 1)};
113 using exec = Kokkos::DefaultHostExecutionSpace;
114 if (local_pressure.extent(1) != layout.total * 9ul) {
115 Kokkos::realloc(Kokkos::WithoutInitializing, local_pressure,
116 exec{}.concurrency(), layout.total * 9ul);
120 auto const &unique_particles = cell_structure->get_unique_particles();
121 auto const n_particles = unique_particles.size();
122 Kokkos::View<int *, Kokkos::LayoutRight, exec> mol_id(
"mol_id", n_particles);
123 for (std::size_t i = 0; i < n_particles; ++i) {
124 mol_id(i) = unique_particles[i]->mol_id();
131 get_ptr(coulomb_pressure_kernel),
132 get_ptr(dipoles_pressure_kernel),
135 thermostat->
dpd.get(),
137 cell_structure->get_unique_particles(),
140 cell_structure->get_aosoa(),
143 thermostat->thermo_switch};
145 auto &bs = cell_structure->bond_state();
147 layout, cell_structure->get_aosoa()};
149 bonds_p_data, bs.pair_list, bs.pair_ids,
get_ptr(coulomb_force_kernel)};
156 pair_p_kernel, *cell_structure, get_interaction_range(),
157 bonded_ias->maximal_cutoff(), make_verlet_criterion,
158 propagation->integ_switch);
161 nonbonded_ias->get_max_seen_particle_type() + 1);
163#ifdef ESPRESSO_ELECTROSTATICS
165 auto const coulomb_pressure = coulomb.calc_pressure_long_range();
166 std::ranges::copy(coulomb_pressure, obs_pressure.coulomb.begin() + 9u);
168#ifdef ESPRESSO_DIPOLES
170 auto const dipoles_pressure = dipoles.calc_pressure_long_range();
171 std::ranges::copy(dipoles_pressure, obs_pressure.dipolar.begin() + 9u);
174#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
175 if (!obs_pressure.virtual_sites.empty()) {
178 obs_pressure.virtual_sites.begin());
182#ifdef ESPRESSO_BOND_CONSTRAINT
183 if (propagation->is_inertial() and bonded_ias->get_n_rigid_bonds() >= 1) {
188 auto const sq_dt =
Utils::sqr(get_time_step());
189 auto const &rigid_bond_virial = bonded_ias->rigid_bond_virial;
190 for (std::size_t bond_id = 0; bond_id < rigid_bond_virial.size();
192 auto const stress = rigid_bond_virial[bond_id] / sq_dt;
193 auto dest = obs_pressure.bonded_contribution(
static_cast<int>(bond_id));
194 for (std::size_t k = 0; k < 9u; ++k)
195 dest[k] += stress[k];
200 obs_pressure.rescale(volume);
202 obs_pressure.mpi_reduce();
Struct holding all information for one particle.