24#ifdef ESPRESSO_ELECTROSTATICS
31#include "communication.hpp"
33#include "system/System.hpp"
39#include <boost/accumulators/accumulators.hpp>
40#include <boost/accumulators/statistics/sum_kahan.hpp>
41#include <boost/mpi/collectives/broadcast.hpp>
57 impl = std::make_unique<Implementation>();
63 std::visit([](
auto const &ptr) { ptr->sanity_checks(); }, *
impl->solver);
82 std::visit([](
auto &ptr) { ptr->on_node_grid_change(); }, *
impl->solver);
102 auto operator()(std::shared_ptr<CoulombP3M>
const &actor)
const {
103 return actor->long_range_pressure();
107 auto operator()(std::shared_ptr<DebyeHueckel>
const &)
const {
111 auto operator()(std::shared_ptr<ReactionField>
const &)
const {
115 template <
typename T>
117 auto operator()(std::shared_ptr<T>
const &)
const {
119 <<
"electrostatics method " << Utils::demangle<T>();
133 auto operator()(std::shared_ptr<CoulombP3M>
const &actor)
const {
134 return actor->p3m_params.r_cut;
137 operator()(std::shared_ptr<ElectrostaticLayerCorrection>
const &actor)
const {
138 return std::max(actor->elc.space_layer,
139 std::visit(*
this, actor->base_solver));
143 auto operator()(std::shared_ptr<CoulombMMM1D>
const &)
const {
144 return std::numeric_limits<double>::infinity();
147#ifdef ESPRESSO_SCAFACOS
148 auto operator()(std::shared_ptr<CoulombScafacos>
const &actor)
const {
149 return actor->get_r_cut();
152 auto operator()(std::shared_ptr<ReactionField>
const &actor)
const {
155 auto operator()(std::shared_ptr<DebyeHueckel>
const &actor)
const {
168 template <
typename T>
void operator()(std::shared_ptr<T>
const &)
const {}
171 void operator()(std::shared_ptr<CoulombP3M>
const &actor)
const {
172 actor->count_charged_particles();
175 operator()(std::shared_ptr<ElectrostaticLayerCorrection>
const &actor)
const {
176 std::visit(*
this, actor->base_solver);
191 template <
class Solver>
192 void operator()(std::shared_ptr<Solver>
const &actor)
const {
193 actor->add_long_range_forces();
197 void operator()(std::shared_ptr<CoulombMMM1D>
const &)
const {}
199 void operator()(std::shared_ptr<DebyeHueckel>
const &)
const {}
200 void operator()(std::shared_ptr<ReactionField>
const &)
const {}
204 template <
class Solver>
205 auto operator()(std::shared_ptr<Solver>
const &actor)
const {
206 return actor->long_range_energy();
210 auto operator()(std::shared_ptr<CoulombMMM1D>
const &)
const {
return 0.; }
212 auto operator()(std::shared_ptr<DebyeHueckel>
const &)
const {
return 0.; }
213 auto operator()(std::shared_ptr<ReactionField>
const &)
const {
return 0.; }
231 using namespace boost::accumulators;
235 auto q_min = std::numeric_limits<double>::infinity();
237 for (
auto const q : charges) {
250 std::vector<double> charges;
251 for (
auto const &p :
system.cell_structure->local_particles()) {
252 charges.emplace_back(p.q());
265 serializer << std::scientific << std::setprecision(4);
267 throw std::runtime_error(
268 "The system is not charge neutral. Please neutralize the system "
269 "before adding a new actor by adding the corresponding counterions "
270 "to the system. Alternatively you can turn off the electroneutrality "
271 "check by supplying check_neutrality=False when creating the actor. "
272 "In this case you may be simulating a non-neutral system which will "
273 "affect physical observables like e.g. the pressure, the chemical "
274 "potentials of charged species or potential energies of the system. "
275 "Since simulations of non charge neutral systems are special please "
276 "make sure you know what you are doing. The relative charge excess "
Vector implementation and trait types for boost qvm interoperability.
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
boost::mpi::communicator comm_cart
The communicator.
int this_node
The number of this node.
constexpr double inactive_cutoff
Special cutoff value for an inactive interaction.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeWarningMsg()
void check_charge_neutrality(System::System const &system, double relative_tolerance)
Check if the system is charge-neutral.
static auto calc_charge_excess_ratio(std::vector< double > const &charges)
Compute the net charge rescaled by the smallest non-zero charge.
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
void operator()(std::shared_ptr< T > const &) const
void operator()(std::shared_ptr< ElectrostaticLayerCorrection > const &actor) const
void operator()(std::shared_ptr< CoulombP3M > const &actor) const
auto operator()(std::shared_ptr< ReactionField > const &) const
auto operator()(std::shared_ptr< Solver > const &actor) const
auto operator()(std::shared_ptr< CoulombMMM1D > const &) const
auto operator()(std::shared_ptr< DebyeHueckel > const &) const
void operator()(std::shared_ptr< ReactionField > const &) const
void operator()(std::shared_ptr< CoulombMMM1D > const &) const
void operator()(std::shared_ptr< Solver > const &actor) const
void operator()(std::shared_ptr< DebyeHueckel > const &) const
auto operator()(std::shared_ptr< ReactionField > const &) const
auto operator()(std::shared_ptr< DebyeHueckel > const &) const
auto operator()(std::shared_ptr< CoulombP3M > const &actor) const
auto operator()(std::shared_ptr< CoulombP3M > const &actor) const
auto operator()(std::shared_ptr< CoulombMMM1D > const &) const
auto operator()(std::shared_ptr< ElectrostaticLayerCorrection > const &actor) const
auto operator()(std::shared_ptr< ReactionField > const &actor) const
auto operator()(std::shared_ptr< DebyeHueckel > const &actor) const
auto operator()(std::shared_ptr< CoulombScafacos > const &actor) const
Utils::Vector9d calc_pressure_long_range() const
double calc_energy_long_range() const
void on_observable_calc()
void sanity_checks() const
void on_cell_structure_change()
void on_periodicity_change()
void calc_long_range_force() const
void on_node_grid_change()
std::unique_ptr< Implementation > impl
Pointer-to-implementation.
bool reinit_on_observable_calc
Whether to reinitialize the solver on observable calculation.
The electrostatic method supports pressure calculation.
void visit_try_catch(Visitor &&visitor, Variant &actor)
Run a kernel on a variant and queue errors.