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/matrix.hpp>
44
45#include <algorithm>
46#include <cstddef>
47#include <memory>
48
49namespace System {
50std::shared_ptr<Observable_stat> System::calculate_pressure() {
51
52 auto obs_pressure_ptr = std::make_shared<Observable_stat>(
53 9ul, static_cast<std::size_t>(bonded_ias->get_next_key()),
54 nonbonded_ias->get_max_seen_particle_type());
55
56 if (long_range_interactions_sanity_checks()) {
57 return obs_pressure_ptr;
58 }
59
60 auto &obs_pressure = *obs_pressure_ptr;
61
62 on_observable_calc();
63
64 auto const volume = box_geo->volume();
65
66 // Kinetic virial — reduction over local particles
67 auto const kinetic = reduce_over_local_particles<Utils::Matrix<double, 3, 3>>(
68 *cell_structure,
69 [](Utils::Matrix<double, 3, 3> &acc, Particle const &p) {
70 if (!p.is_virtual())
71 acc += Utils::tensor_product(p.v(), p.mass() * p.v());
72 },
73 [](auto &a, auto const &b) { a += b; });
74 std::ranges::copy(Utils::flatten(kinetic), obs_pressure.kinetic_lin.begin());
75
76 auto const coulomb_force_kernel = coulomb.pair_force_kernel();
77 auto const coulomb_pressure_kernel = coulomb.pair_pressure_kernel();
78
79 VerletCriterion<> const verlet_criterion{*this,
80 cell_structure->get_verlet_skin(),
81 get_interaction_range(),
82 coulomb.cutoff(),
83 dipoles.cutoff(),
85 update_cabana_state(*cell_structure, verlet_criterion,
86 get_interaction_range(), propagation->integ_switch);
87
88 PressureBinLayout layout{
89 static_cast<std::size_t>(bonded_ias->get_next_key()),
90 std::size_t(nonbonded_ias->get_max_seen_particle_type() + 1)};
91
92 using exec = Kokkos::DefaultExecutionSpace;
93 Kokkos::View<double **, Kokkos::LayoutRight> local_pressure(
94 "local_pressure", exec().concurrency(), layout.total * 9);
95
96 auto const &unique_particles = cell_structure->get_unique_particles();
97 auto const n_particles = static_cast<int>(unique_particles.size());
98 Kokkos::View<int *> mol_id_view("mol_id", n_particles);
99 auto mol_id_host = Kokkos::create_mirror_view(mol_id_view);
100 for (int i = 0; i < n_particles; ++i)
101 mol_id_host(i) = unique_particles[i]->mol_id();
102 Kokkos::deep_copy(mol_id_view, mol_id_host);
103
104 PressureKernel pair_p_kernel{*bonded_ias,
105 *nonbonded_ias,
106 coulomb,
107 get_ptr(coulomb_force_kernel),
108 get_ptr(coulomb_pressure_kernel),
109 *box_geo,
110 cell_structure->get_unique_particles(),
111 local_pressure,
112 layout,
113 cell_structure->get_aosoa(),
114 mol_id_view,
115 maximal_cutoff(),
116 thermostat->thermo_switch};
117
118 auto &bs = cell_structure->bond_state();
119 BondsPressureKernelData bonds_p_data{*bonded_ias, *box_geo, local_pressure,
120 layout, cell_structure->get_aosoa()};
121 PairBondsPressureKernel pair_bp_kernel{
122 bonds_p_data, bs.pair_list, bs.pair_ids, get_ptr(coulomb_force_kernel)};
123 AngleBondsPressureKernel angle_bp_kernel{bonds_p_data, bs.angle_list,
124 bs.angle_ids};
125 NullDihedralPressureKernel null_dih_kernel{};
126
127 cabana_short_range(pair_bp_kernel, angle_bp_kernel, null_dih_kernel,
128 pair_p_kernel, *cell_structure, get_interaction_range(),
129 bonded_ias->maximal_cutoff(), verlet_criterion,
130 propagation->integ_switch);
131
132 reduce_cabana_pressure(local_pressure, layout, obs_pressure, *bonded_ias,
133 nonbonded_ias->get_max_seen_particle_type() + 1);
134
135#ifdef ESPRESSO_ELECTROSTATICS
136 /* calculate k-space part of electrostatic interaction. */
137 auto const coulomb_pressure = coulomb.calc_pressure_long_range();
138 std::ranges::copy(coulomb_pressure, obs_pressure.coulomb.begin() + 9u);
139#endif
140#ifdef ESPRESSO_DIPOLES
141 /* calculate k-space part of magnetostatic interaction. */
142 dipoles.calc_pressure_long_range();
143#endif
144
145#ifdef ESPRESSO_VIRTUAL_SITES_RELATIVE
146 if (!obs_pressure.virtual_sites.empty()) {
147 auto const vs_pressure = vs_relative_pressure_tensor(*cell_structure);
148 std::ranges::copy(Utils::flatten(vs_pressure),
149 obs_pressure.virtual_sites.begin());
150 }
151#endif
152
153 obs_pressure.rescale(volume);
154
155 obs_pressure.mpi_reduce();
156 return obs_pressure_ptr;
157}
158} // 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:50
Returns true if the particles are to be considered for short range interactions.
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
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 > 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
ESPRESSO_ATTR_ALWAYS_INLINE void update_cabana_state(CellStructure &cell_structure, auto const &verlet_criterion, double const pair_cutoff, auto const integ_switch)
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.
Definition Particle.hpp:435
Matrix representation with static size.
Definition matrix.hpp:65