ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
pressure.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2026 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <config/config.hpp>
23
24#include "BoxGeometry.hpp"
25#include "Observable_stat.hpp"
26#include "Particle.hpp"
36#include "pressure_cabana.hpp"
37#include "pressure_inline.hpp"
39#include "system/System.hpp"
41
42#include <utils/Vector.hpp>
43#include <utils/math/sqr.hpp>
44#include <utils/matrix.hpp>
45
46#include <algorithm>
47#include <cstddef>
48#include <memory>
49
50namespace System {
51std::shared_ptr<Observable_stat> System::calculate_pressure() {
52
53 auto obs_pressure_ptr = std::make_shared<Observable_stat>(
54 9ul, static_cast<std::size_t>(bonded_ias->get_next_key()),
55 nonbonded_ias->get_max_seen_particle_type());
56
57 if (long_range_interactions_sanity_checks()) {
58 return obs_pressure_ptr;
59 }
60
62
63 on_observable_calc();
64
65 auto const volume = box_geo->volume();
66
67 // Kinetic virial — reduction over local particles
69 *cell_structure,
70 [](Utils::Matrix<double, 3, 3> &acc, Particle const &p) {
71 if (!p.is_virtual())
72 acc += Utils::tensor_product(p.v(), p.mass() * p.v());
73 },
74 [](auto &a, auto const &b) { a += b; });
75 std::ranges::copy(Utils::flatten(kinetic), obs_pressure.kinetic_lin.begin());
76
77 auto const coulomb_force_kernel = coulomb.pair_force_kernel();
78 auto const coulomb_pressure_kernel = coulomb.pair_pressure_kernel();
79
81 cell_structure->get_verlet_skin(),
82 get_interaction_range(),
83 coulomb.cutoff(),
84 dipoles.cutoff(),
87 get_interaction_range(), propagation->integ_switch);
88
89 PressureBinLayout layout{
90 static_cast<std::size_t>(bonded_ias->get_next_key()),
91 std::size_t(nonbonded_ias->get_max_seen_particle_type() + 1)};
92
93 using exec = Kokkos::DefaultHostExecutionSpace;
94 Kokkos::View<double **, Kokkos::LayoutRight, exec> local_pressure(
95 "local_pressure", exec().concurrency(), layout.total * 9);
96
97 auto const &unique_particles = cell_structure->get_unique_particles();
98 auto const n_particles = unique_particles.size();
99 Kokkos::View<int *, Kokkos::LayoutRight, exec> mol_id("mol_id", n_particles);
100 for (std::size_t i = 0; i < n_particles; ++i) {
101 mol_id(i) = unique_particles[i]->mol_id();
102 }
103
104 PressureKernel pair_p_kernel{*bonded_ias,
105 *nonbonded_ias,
106 coulomb,
109 *box_geo,
110#ifdef ESPRESSO_DPD
111 thermostat->dpd.get(),
112#endif
113 cell_structure->get_unique_particles(),
114 local_pressure,
115 layout,
116 cell_structure->get_aosoa(),
117 mol_id,
118 maximal_cutoff(),
119 thermostat->thermo_switch};
120
121 auto &bs = cell_structure->bond_state();
122 BondsPressureKernelData bonds_p_data{*bonded_ias, *box_geo, local_pressure,
123 layout, cell_structure->get_aosoa()};
125 bonds_p_data, bs.pair_list, bs.pair_ids, get_ptr(coulomb_force_kernel)};
127 bs.angle_ids};
129 bs.dihedral_ids};
130
132 pair_p_kernel, *cell_structure, get_interaction_range(),
133 bonded_ias->maximal_cutoff(), verlet_criterion,
134 propagation->integ_switch);
135
136 reduce_cabana_pressure(local_pressure, layout, obs_pressure, *bonded_ias,
137 nonbonded_ias->get_max_seen_particle_type() + 1);
138
139#ifdef ESPRESSO_ELECTROSTATICS
140 /* calculate k-space part of electrostatic interaction. */
141 auto const coulomb_pressure = coulomb.calc_pressure_long_range();
142 std::ranges::copy(coulomb_pressure, obs_pressure.coulomb.begin() + 9u);
143#endif
144#ifdef ESPRESSO_DIPOLES
145 /* calculate k-space part of magnetostatic interaction. */
146 dipoles.calc_pressure_long_range();
147#endif
148
149#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
150 if (!obs_pressure.virtual_sites.empty()) {
151 auto const vs_pressure = vs_relative_pressure_tensor(*cell_structure);
152 std::ranges::copy(Utils::flatten(vs_pressure),
153 obs_pressure.virtual_sites.begin());
154 }
155#endif
156
157#ifdef ESPRESSO_BOND_CONSTRAINT
158 if (propagation->is_inertial() and bonded_ias->get_n_rigid_bonds() >= 1) {
159 // rigid_bond_virial was accumulated bond-by-bond inside
160 // correct_position_shake() during the last integration step, so it is
161 // already correct regardless of how many rigid bonds a particle
162 // participates in; only the deferred 1/dt^2 factor is applied here.
163 auto const sq_dt = Utils::sqr(get_time_step());
164 auto const &rigid_bond_virial = bonded_ias->rigid_bond_virial;
165 for (std::size_t bond_id = 0; bond_id < rigid_bond_virial.size();
166 ++bond_id) {
167 auto const stress = rigid_bond_virial[bond_id] / sq_dt;
168 auto dest = obs_pressure.bonded_contribution(static_cast<int>(bond_id));
169 for (std::size_t k = 0; k < 9u; ++k)
170 dest[k] += stress[k];
171 }
172 }
173#endif // ESPRESSO_BOND_CONSTRAINT
174
175 obs_pressure.rescale(volume);
176
177 obs_pressure.mpi_reduce();
178 return obs_pressure_ptr;
179}
180} // namespace System
Vector implementation and trait types for boost qvm interoperability.
Data structures for bonded interactions.
std::shared_ptr< Observable_stat > calculate_pressure()
Calculate the pressure from a virial expansion.
Definition pressure.cpp:51
Returns true if the particles are to be considered for short range interactions.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
constexpr double inactive_cutoff
Special cutoff value for an inactive interaction.
Definition config.hpp:53
const T * get_ptr(std::optional< T > const &opt)
Matrix implementation and trait types for boost qvm interoperability.
void flatten(Range const &v, OutputIterator out)
Flatten a range of ranges.
Definition flatten.hpp:56
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
Matrix< T, N, M > tensor_product(const Vector< T, N > &x, const Vector< T, M > &y)
Various procedures concerning interactions between particles.
static void reduce_cabana_pressure(Kokkos::View< double **, Kokkos::LayoutRight, Kokkos::HostSpace > const &local_pressure, PressureBinLayout const &layout, Observable_stat &obs, BondedInteractionsMap const &bonded_ias, int n_types)
Utils::Matrix< double, 3, 3 > vs_relative_pressure_tensor(CellStructure const &cell_structure)
Definition relative.cpp:194
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)
ESPRESSO_ATTR_ALWAYS_INLINE void update_cabana_state(CellStructure &cell_structure, auto const &verlet_criterion, double const pair_cutoff, auto const integ_switch)
Struct holding all information for one particle.
Definition Particle.hpp:436
DPDThermostat const * dpd
Matrix representation with static size.
Definition matrix.hpp:65