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 <cstddef>
39#include <memory>
40#include <optional>
41#include <stdexcept>
42#include <type_traits>
43#include <utility>
44
45template <typename FloatType>
46struct p3m_data_struct_coulomb : public p3m_data_struct<FloatType> {
47 using p3m_data_struct<FloatType>::p3m_data_struct;
48
49 /** number of charged particles. */
50 std::size_t sum_qpart = 0;
51 /** Sum of square of charges. */
52 double sum_q2 = 0.;
53 /** square of sum of charges. */
54 double square_sum_q = 0.;
55
57};
58
59#ifdef CUDA
60struct P3MGpuParams;
61#endif
62
63template <typename FloatType, Arch Architecture>
64struct CoulombP3MImpl : public CoulombP3M {
65 ~CoulombP3MImpl() override = default;
66
67 /** @brief Coulomb P3M parameters. */
69
70private:
71 /** @brief Coulomb P3M meshes and FFT algorithm. */
72 std::unique_ptr<p3m_data_struct_coulomb<FloatType>> p3m_impl;
73 int tune_timings;
74 std::pair<std::optional<int>, std::optional<int>> tune_limits;
75 bool tune_verbose;
76 bool check_complex_residuals;
77 bool m_is_tuned;
78
79public:
81 std::unique_ptr<p3m_data_struct_coulomb<FloatType>> &&p3m_handle,
82 double prefactor, int tune_timings, bool tune_verbose,
83 decltype(tune_limits) tune_limits, bool check_complex_residuals)
84 : CoulombP3M(p3m_handle->params), p3m{*p3m_handle},
85 p3m_impl{std::move(p3m_handle)}, tune_timings{tune_timings},
86 tune_limits{std::move(tune_limits)}, tune_verbose{tune_verbose},
87 check_complex_residuals{check_complex_residuals} {
88
89 if (tune_timings <= 0) {
90 throw std::domain_error("Parameter 'timings' must be > 0");
91 }
92 m_is_tuned = not p3m.params.tuning;
93 p3m.params.tuning = false;
95 }
96
97 void init() override {
98 if constexpr (Architecture == Arch::CPU) {
100 }
101#ifdef CUDA
102 if constexpr (Architecture == Arch::GPU) {
104 }
105#endif
106 }
107 void tune() override;
108 void count_charged_particles() override;
109 void count_charged_particles_elc(std::size_t n, double sum_q2,
110 double square_sum_q) override {
111 p3m.sum_qpart = n;
112 p3m.sum_q2 = sum_q2;
113 p3m.square_sum_q = square_sum_q;
114 }
115 void adapt_epsilon_elc() override {
116 p3m.params.epsilon = P3M_EPSILON_METALLIC;
117 }
118
119 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
120 [[nodiscard]] bool is_gpu() const noexcept override {
121 return Architecture == Arch::GPU;
122 }
123 [[nodiscard]] bool is_double_precision() const noexcept override {
124 return std::is_same_v<FloatType, double>;
125 }
126
127 void on_activation() override {
128#ifdef CUDA
129 if constexpr (Architecture == Arch::GPU) {
130 request_gpu();
131 }
132#endif
134 tune();
135#ifdef CUDA
136 if constexpr (Architecture == Arch::GPU) {
137 if (is_tuned()) {
139 }
140 }
141#endif
142 }
143
144 double long_range_energy(ParticleRange const &particles) override {
145 return long_range_kernel(false, true, particles);
146 }
147
148 void add_long_range_forces(ParticleRange const &particles) override {
149 if constexpr (Architecture == Arch::CPU) {
150 long_range_kernel(true, false, particles);
151 }
152#ifdef CUDA
153 if constexpr (Architecture == Arch::GPU) {
154 add_long_range_forces_gpu(particles);
155 }
156#endif
157 }
158
159 Utils::Vector9d long_range_pressure(ParticleRange const &particles) override;
160
161 void charge_assign(ParticleRange const &particles) override;
162 void assign_charge(double q, Utils::Vector3d const &real_pos,
163 bool skip_cache) override;
164 void prepare_fft_mesh(bool reset_weights) override {
165 if (reset_weights) {
166 p3m.inter_weights.reset(p3m.params.cao);
167 }
168 for (int i = 0; i < p3m.local_mesh.size; i++) {
169 p3m.mesh.rs_scalar[i] = FloatType(0);
170 }
171 }
172
173protected:
174 /** Compute the k-space part of forces and energies. */
175 double long_range_kernel(bool force_flag, bool energy_flag,
176 ParticleRange const &particles);
177 void calc_influence_function_force() override;
178 void calc_influence_function_energy() override;
179 void scaleby_box_l() override;
180 void init_cpu_kernels();
181#ifdef CUDA
182 void init_gpu_kernels();
183 void add_long_range_forces_gpu(ParticleRange const &particles);
184 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
185 void request_gpu() const;
186#endif
187};
188
189template <typename FloatType, Arch Architecture,
190 template <typename> class FFTBackendImpl,
191 template <typename> class P3MFFTMeshImpl, class... Args>
192std::shared_ptr<CoulombP3M> new_p3m_handle(P3MParameters &&p3m,
193 Args &&...args) {
194 auto obj = std::make_shared<CoulombP3MImpl<FloatType, Architecture>>(
195 std::make_unique<p3m_data_struct_coulomb<FloatType>>(std::move(p3m)),
196 std::forward<Args>(args)...);
197 obj->p3m.template make_mesh_instance<P3MFFTMeshImpl<FloatType>>();
198 obj->p3m.template make_fft_instance<FFTBackendImpl<FloatType>>();
199 return obj;
200}
201
202#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
P3M kernel architecture.
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:192
static SteepestDescentParameters params
Currently active steepest descent instance.
void charge_assign(ParticleRange const &particles) override
Definition p3m.cpp:325
double long_range_energy(ParticleRange const &particles) override
Definition p3m.impl.hpp:144
void tune() override
Definition p3m.cpp:810
bool is_gpu() const noexcept override
Definition p3m.impl.hpp:120
bool is_tuned() const noexcept override
Definition p3m.impl.hpp:119
void assign_charge(double q, Utils::Vector3d const &real_pos, bool skip_cache) override
Definition p3m.cpp:337
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
Definition p3m.cpp:139
void add_long_range_forces(ParticleRange const &particles) override
Definition p3m.impl.hpp:148
void count_charged_particles_elc(std::size_t n, double sum_q2, double square_sum_q) override
Definition p3m.impl.hpp:109
void scaleby_box_l() override
Definition p3m.cpp:908
void calc_influence_function_force() override
Calculate the optimal influence function of .
Definition p3m.cpp:128
Utils::Vector9d long_range_pressure(ParticleRange const &particles) override
Definition p3m.cpp:398
void init_cpu_kernels()
Definition p3m.cpp:250
bool is_double_precision() const noexcept override
Definition p3m.impl.hpp:123
~CoulombP3MImpl() override=default
void on_activation() override
Definition p3m.impl.hpp:127
CoulombP3MImpl(std::unique_ptr< p3m_data_struct_coulomb< FloatType > > &&p3m_handle, double prefactor, int tune_timings, bool tune_verbose, decltype(tune_limits) tune_limits, bool check_complex_residuals)
Definition p3m.impl.hpp:80
void count_charged_particles() override
Definition p3m.cpp:99
void init() override
Definition p3m.impl.hpp:97
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:456
std::shared_ptr< P3MGpuParams > m_gpu_data
Definition p3m.impl.hpp:184
void request_gpu() const
Definition p3m.cpp:959
void prepare_fft_mesh(bool reset_weights) override
Definition p3m.impl.hpp:164
void init_gpu_kernels()
Definition p3m.cpp:946
void add_long_range_forces_gpu(ParticleRange const &particles)
Definition p3m.cpp:921
p3m_data_struct_coulomb< FloatType > & p3m
Coulomb P3M parameters.
Definition p3m.impl.hpp:68
void adapt_epsilon_elc() override
Definition p3m.impl.hpp:115
P3M solver.
Definition p3m.hpp:56
void sanity_checks() const
Definition p3m.hpp:80
Structure to hold P3M parameters and some dependent variables.
std::size_t sum_qpart
number of charged particles.
Definition p3m.impl.hpp:50
double sum_q2
Sum of square of charges.
Definition p3m.impl.hpp:52
double square_sum_q
square of sum of charges.
Definition p3m.impl.hpp:54
p3m_interpolation_cache inter_weights
Definition p3m.impl.hpp:56
Base class for the electrostatics and magnetostatics P3M algorithms.