ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
npt.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include "npt.hpp"
20
21#ifdef ESPRESSO_NPT
22
23#include "BoxGeometry.hpp"
24#include "PropagationMode.hpp"
26#include "communication.hpp"
27#include "config/config.hpp"
29#include "errorhandling.hpp"
32#include "system/System.hpp"
33
34#include <utils/Vector.hpp>
36
37#include <boost/mpi/collectives.hpp>
38
39#include <algorithm>
40#include <cmath>
41#include <stdexcept>
42
44 boost::mpi::broadcast(comm_cart, nptiso->p_epsilon, 0);
45 boost::mpi::broadcast(comm_cart, nptiso->volume, 0);
46 boost::mpi::broadcast(comm_cart, npt_inst_pressure->p_inst, 0);
47}
48
50 System::System const &system) const {
51#ifdef ESPRESSO_ELECTROSTATICS
52 if (dimension < 3 and not cubic_box and system.coulomb.impl->solver) {
53 throw std::runtime_error("If electrostatics is being used you must "
54 "use the cubic box NpT.");
55 }
56#endif
57#ifdef ESPRESSO_DIPOLES
58 if (dimension < 3 and not cubic_box and system.dipoles.impl->solver) {
59 throw std::runtime_error("If magnetostatics is being used you must "
60 "use the cubic box NpT.");
61 }
62#endif
63}
64
65NptIsoParameters::NptIsoParameters(double ext_pressure, double piston,
66 Utils::Vector<bool, 3> const &rescale,
67 bool cubic_box)
68 : piston{piston}, inv_piston{piston}, p_ext{ext_pressure},
69 cubic_box{cubic_box} {
70
71 if (ext_pressure < 0.0) {
72 throw std::runtime_error("The external pressure must be positive");
73 }
74 if (piston <= 0.0) {
75 throw std::runtime_error("The piston mass must be positive");
76 }
77
78 /* set the NpT geometry */
79 for (auto const i : {0u, 1u, 2u}) {
80 if (rescale[i]) {
82 dimension += 1;
83 non_const_dim = static_cast<int>(i);
84 }
85 }
86
87 if (dimension == 0 or non_const_dim == -1) {
88 throw std::runtime_error(
89 "You must enable at least one of the x y z components "
90 "as fluctuating dimension(s) for box length motion");
91 }
92}
93
95 return {static_cast<bool>(geometry & nptgeom_dir[0]),
96 static_cast<bool>(geometry & nptgeom_dir[1]),
97 static_cast<bool>(geometry & nptgeom_dir[2])};
98}
99
100void System::System::npt_ensemble_init(bool recalc_forces) {
101 nptiso->inv_piston = 1. / nptiso->piston;
102 nptiso->volume =
103 std::pow(box_geo->length()[nptiso->non_const_dim], nptiso->dimension);
104 if (recalc_forces) {
105 npt_inst_pressure->p_inst = Utils::Vector2d{};
106 npt_inst_pressure->p_vir = Utils::Vector3d{};
107 npt_inst_pressure->p_vel = Utils::Vector3d{};
108 }
109
110 auto const particle_number =
111 ::System::get_system().cell_structure->local_particles().size();
112 nptiso->particle_number =
113 boost::mpi::all_reduce(::comm_cart, particle_number, std::plus<>());
114
115 auto const dt = ::System::get_system().get_time_step();
116 nptiso->half_dt_inv_piston = 0.5 * dt * nptiso->inv_piston;
117 nptiso->half_dt_inv_piston_and_Nf = -nptiso->half_dt_inv_piston;
118 if (particle_number > 1) {
119 nptiso->half_dt_inv_piston_and_Nf *=
120 (1. + 1. / static_cast<double>(particle_number - 1));
121 }
122
123 auto &mass_list = nptiso->mass_list;
124 mass_list.clear();
125 for (auto &p : cell_structure->local_particles()) {
126 mass_list.emplace_back(p.mass());
127 }
128 mass_list.erase(std::ranges::unique(mass_list).begin(), mass_list.end());
130 if (::this_node == 0) {
131 mass_list.erase(std::ranges::unique(mass_list).begin(), mass_list.end());
132 std::ranges::sort(mass_list);
133 }
134 boost::mpi::broadcast(::comm_cart, mass_list, 0);
135}
136
138 if (has_npt_enabled()) {
139 npt_inst_pressure->p_vir[0] += energy;
140 }
141}
142#endif // ESPRESSO_NPT
Vector implementation and trait types for boost qvm interoperability.
Main system class.
auto get_time_step() const
Get time_step.
void npt_ensemble_init(bool recalc_forces)
Reinitialize the NpT state.
Definition npt.cpp:100
void npt_add_virial_contribution(double energy)
Definition npt.cpp:137
void synchronize_npt_state()
Synchronize NpT state such as instantaneous and average pressure.
Definition npt.cpp:43
std::shared_ptr< CellStructure > cell_structure
boost::mpi::communicator comm_cart
The communicator.
int this_node
The number of this node.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
System & get_system()
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
Exports for the NpT code.
void coulomb_dipole_sanity_checks(System::System const &system) const
Definition npt.cpp:49
int geometry
geometry information for the NpT integrator.
Definition npt.hpp:72
static constexpr std::array< int, 3 > nptgeom_dir
Definition npt.hpp:88
int non_const_dim
An index to one of the non-constant dimensions.
Definition npt.hpp:85
Utils::Vector< bool, 3 > get_direction() const
Definition npt.cpp:94
NptIsoParameters()=default
int dimension
The number of dimensions in which NpT boxlength motion is coupled to particles.
Definition npt.hpp:75
double piston
mass of a virtual piston representing the shaken box
Definition npt.hpp:47