ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
p3m.impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2024 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#pragma once
23
24#include "config/config.hpp"
25
26#ifdef P3M
27
29
30#include "p3m/common.hpp"
31#include "p3m/data_struct.hpp"
32#include "p3m/interpolation.hpp"
33
34#include "ParticleRange.hpp"
35
36#include <utils/Vector.hpp>
37
38#include <memory>
39#include <stdexcept>
40#include <type_traits>
41#include <utility>
42
43template <typename FloatType>
44struct p3m_data_struct_coulomb : public p3m_data_struct<FloatType> {
45 using p3m_data_struct<FloatType>::p3m_data_struct;
46
47 /** number of charged particles (only on head node). */
48 int sum_qpart = 0;
49 /** Sum of square of charges (only on head node). */
50 double sum_q2 = 0.;
51 /** square of sum of charges (only on head node). */
52 double square_sum_q = 0.;
53
55};
56
57#ifdef CUDA
58struct P3MGpuParams;
59#endif
60
61template <typename FloatType, Arch Architecture>
62struct CoulombP3MImpl : public CoulombP3M {
63 ~CoulombP3MImpl() override = default;
64
65 /** @brief Coulomb P3M parameters. */
67
68private:
69 /** @brief Coulomb P3M meshes and FFT algorithm. */
70 std::unique_ptr<p3m_data_struct_coulomb<FloatType>> p3m_impl;
71 int tune_timings;
72 bool tune_verbose;
73 bool check_complex_residuals;
74 bool m_is_tuned;
75
76public:
78 std::unique_ptr<p3m_data_struct_coulomb<FloatType>> &&p3m_handle,
79 double prefactor, int tune_timings, bool tune_verbose,
80 bool check_complex_residuals)
81 : CoulombP3M(p3m_handle->params), p3m{*p3m_handle},
82 p3m_impl{std::move(p3m_handle)}, tune_timings{tune_timings},
83 tune_verbose{tune_verbose},
84 check_complex_residuals{check_complex_residuals} {
85
86 if (tune_timings <= 0) {
87 throw std::domain_error("Parameter 'timings' must be > 0");
88 }
89 m_is_tuned = not p3m.params.tuning;
90 p3m.params.tuning = false;
92 }
93
94 void init() override {
95 if constexpr (Architecture == Arch::CPU) {
97 }
98#ifdef CUDA
99 if constexpr (Architecture == Arch::GPU) {
101 }
102#endif
103 }
104 void tune() override;
105 void count_charged_particles() override;
106 void count_charged_particles_elc(int n, double sum_q2,
107 double square_sum_q) override {
108 p3m.sum_qpart = n;
109 p3m.sum_q2 = sum_q2;
110 p3m.square_sum_q = square_sum_q;
111 }
112 void adapt_epsilon_elc() override {
113 p3m.params.epsilon = P3M_EPSILON_METALLIC;
114 }
115
116 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
117 [[nodiscard]] bool is_gpu() const noexcept override {
118 return Architecture == Arch::GPU;
119 }
120 [[nodiscard]] bool is_double_precision() const noexcept override {
121 return std::is_same_v<FloatType, double>;
122 }
123
124 void on_activation() override {
125#ifdef CUDA
126 if constexpr (Architecture == Arch::GPU) {
127 request_gpu();
128 }
129#endif
131 tune();
132#ifdef CUDA
133 if constexpr (Architecture == Arch::GPU) {
134 if (is_tuned()) {
136 }
137 }
138#endif
139 }
140
141 double long_range_energy(ParticleRange const &particles) override {
142 return long_range_kernel(false, true, particles);
143 }
144
145 void add_long_range_forces(ParticleRange const &particles) override {
146 if constexpr (Architecture == Arch::CPU) {
147 long_range_kernel(true, false, particles);
148 }
149#ifdef CUDA
150 if constexpr (Architecture == Arch::GPU) {
151 add_long_range_forces_gpu(particles);
152 }
153#endif
154 }
155
156 Utils::Vector9d long_range_pressure(ParticleRange const &particles) override;
157
158 void charge_assign(ParticleRange const &particles) override;
159 void assign_charge(double q, Utils::Vector3d const &real_pos,
160 bool skip_cache) override;
161 void prepare_fft_mesh(bool reset_weights) override {
162 if (reset_weights) {
163 p3m.inter_weights.reset(p3m.params.cao);
164 }
165 for (int i = 0; i < p3m.local_mesh.size; i++) {
166 p3m.mesh.rs_scalar[i] = FloatType(0);
167 }
168 }
169
170protected:
171 /** Compute the k-space part of forces and energies. */
172 double long_range_kernel(bool force_flag, bool energy_flag,
173 ParticleRange const &particles);
174 void calc_influence_function_force() override;
175 void calc_influence_function_energy() override;
176 void scaleby_box_l() override;
177 void init_cpu_kernels();
178#ifdef CUDA
179 void init_gpu_kernels();
180 void add_long_range_forces_gpu(ParticleRange const &particles);
181 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
182 void request_gpu() const;
183#endif
184};
185
186template <typename FloatType, Arch Architecture,
187 template <typename> class FFTBackendImpl,
188 template <typename> class P3MFFTMeshImpl, class... Args>
189std::shared_ptr<CoulombP3M> new_p3m_handle(P3MParameters &&p3m,
190 Args &&...args) {
191 auto obj = std::make_shared<CoulombP3MImpl<FloatType, Architecture>>(
192 std::make_unique<p3m_data_struct_coulomb<FloatType>>(std::move(p3m)),
193 std::forward<Args>(args)...);
194 obj->p3m.template make_mesh_instance<P3MFFTMeshImpl<FloatType>>();
195 obj->p3m.template make_fft_instance<FFTBackendImpl<FloatType>>();
196 return obj;
197}
198
199#endif // P3M
Vector implementation and trait types for boost qvm interoperability.
void set_prefactor(double new_prefactor)
double prefactor
Electrostatics prefactor.
A range of particles.
Cache for interpolation weights.
This file contains the defaults for ESPResSo.
Common functions for dipolar and charge P3M.
Arch
auto constexpr P3M_EPSILON_METALLIC
This value indicates metallic boundary conditions.
P3M algorithm for long-range Coulomb interaction.
std::shared_ptr< CoulombP3M > new_p3m_handle(P3MParameters &&p3m, Args &&...args)
Definition p3m.impl.hpp:189
static SteepestDescentParameters params
Currently active steepest descent instance.
void charge_assign(ParticleRange const &particles) override
Definition p3m.cpp:321
double long_range_energy(ParticleRange const &particles) override
Definition p3m.impl.hpp:141
void tune() override
Definition p3m.cpp:758
bool is_gpu() const noexcept override
Definition p3m.impl.hpp:117
bool is_tuned() const noexcept override
Definition p3m.impl.hpp:116
void assign_charge(double q, Utils::Vector3d const &real_pos, bool skip_cache) override
Definition p3m.cpp:333
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
Definition p3m.cpp:138
void add_long_range_forces(ParticleRange const &particles) override
Definition p3m.impl.hpp:145
void count_charged_particles_elc(int n, double sum_q2, double square_sum_q) override
Definition p3m.impl.hpp:106
CoulombP3MImpl(std::unique_ptr< p3m_data_struct_coulomb< FloatType > > &&p3m_handle, double prefactor, int tune_timings, bool tune_verbose, bool check_complex_residuals)
Definition p3m.impl.hpp:77
void scaleby_box_l() override
Definition p3m.cpp:856
void calc_influence_function_force() override
Calculate the optimal influence function of .
Definition p3m.cpp:127
Utils::Vector9d long_range_pressure(ParticleRange const &particles) override
Definition p3m.cpp:394
void init_cpu_kernels()
Definition p3m.cpp:246
bool is_double_precision() const noexcept override
Definition p3m.impl.hpp:120
~CoulombP3MImpl() override=default
void on_activation() override
Definition p3m.impl.hpp:124
void count_charged_particles() override
Definition p3m.cpp:98
void init() override
Definition p3m.impl.hpp:94
double long_range_kernel(bool force_flag, bool energy_flag, ParticleRange const &particles)
Compute the k-space part of forces and energies.
Definition p3m.cpp:452
std::shared_ptr< P3MGpuParams > m_gpu_data
Definition p3m.impl.hpp:181
void request_gpu() const
Definition p3m.cpp:907
void prepare_fft_mesh(bool reset_weights) override
Definition p3m.impl.hpp:161
void init_gpu_kernels()
Definition p3m.cpp:894
void add_long_range_forces_gpu(ParticleRange const &particles)
Definition p3m.cpp:869
p3m_data_struct_coulomb< FloatType > & p3m
Coulomb P3M parameters.
Definition p3m.impl.hpp:66
void adapt_epsilon_elc() override
Definition p3m.impl.hpp:112
P3M solver.
Definition p3m.hpp:55
void sanity_checks() const
Definition p3m.hpp:79
Structure to hold P3M parameters and some dependent variables.
double sum_q2
Sum of square of charges (only on head node).
Definition p3m.impl.hpp:50
double square_sum_q
square of sum of charges (only on head node).
Definition p3m.impl.hpp:52
int sum_qpart
number of charged particles (only on head node).
Definition p3m.impl.hpp:48
p3m_interpolation_cache inter_weights
Definition p3m.impl.hpp:54
Base class for the electrostatics and magnetostatics P3M algorithms.