Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
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 "ParticleRange.hpp"
31#include "p3m/common.hpp"
32#include "p3m/data_struct.hpp"
33#include "p3m/interpolation.hpp"
34#include "p3m/send_mesh.hpp"
35
36#include <utils/Vector.hpp>
37#include <utils/index.hpp>
38
39#include <algorithm>
40#include <complex>
41#include <cstddef>
42#include <memory>
43#include <optional>
44#include <stdexcept>
45#include <type_traits>
46#include <utility>
47
48template <typename FloatType> class P3MFFT;
49
50template <typename FloatType>
51struct CoulombP3MState : public P3MStateCommon<FloatType> {
52 using P3MStateCommon<FloatType>::P3MStateCommon;
53
55
56 /** number of charged particles. */
57 std::size_t sum_qpart = 0;
58 /** Sum of square of charges. */
59 double sum_q2 = 0.;
60 /** square of sum of charges. */
61 double square_sum_q = 0.;
62
64
65 /* fields */
66 std::vector<FloatType> rs_charge_density;
67 std::vector<std::complex<FloatType>> ks_charge_density;
68 std::array<std::vector<FloatType>, 3> rs_E_fields;
69 std::vector<std::complex<FloatType>> ks_E_fields_storage;
70 std::vector<std::complex<FloatType>> rs_E_fields_no_halo;
72 std::shared_ptr<P3MFFT<FloatType>> fft;
73};
74
75#ifdef CUDA
76struct P3MGpuParams;
77#endif
78
79template <typename FloatType, Arch Architecture>
80struct CoulombP3MImpl : public CoulombP3M {
81 ~CoulombP3MImpl() override = default;
82
83 /** @brief Coulomb P3M parameters. */
85
86private:
87 std::unique_ptr<CoulombP3MState<FloatType>> p3m_state_ptr;
88 int tune_timings;
89 std::pair<std::optional<int>, std::optional<int>> tune_limits;
90 bool tune_verbose;
91 bool check_complex_residuals;
92 bool m_is_tuned;
93
94 constexpr const Utils::Vector3i get_memory_layout() const {
95 auto constexpr memory_order =
96 std::remove_reference<decltype(p3m)>::type::memory_order;
97 if constexpr (memory_order == Utils::MemoryOrder::COLUMN_MAJOR) {
98 return {2, 1, 0};
99 }
100 return {0, 1, 2};
101 }
102
103public:
104 CoulombP3MImpl(std::unique_ptr<CoulombP3MState<FloatType>> &&p3m_state,
105 double prefactor, int tune_timings, bool tune_verbose,
106 decltype(tune_limits) tune_limits,
107 bool check_complex_residuals)
108 : CoulombP3M(p3m_state->params), p3m{*p3m_state},
109 p3m_state_ptr{std::move(p3m_state)}, tune_timings{tune_timings},
110 tune_limits{std::move(tune_limits)}, tune_verbose{tune_verbose},
111 check_complex_residuals{check_complex_residuals} {
112
113 if (tune_timings <= 0) {
114 throw std::domain_error("Parameter 'timings' must be > 0");
115 }
116 m_is_tuned = not p3m.params.tuning;
117 p3m.params.tuning = false;
119 }
120
121 void init() override {
122 if constexpr (Architecture == Arch::CPU) {
124 }
125#ifdef CUDA
126 if constexpr (Architecture == Arch::GPU) {
128 }
129#endif
130 }
131 void tune() override;
132 void count_charged_particles() override;
133 void count_charged_particles_elc(std::size_t n, double sum_q2,
134 double square_sum_q) override {
135 p3m.sum_qpart = n;
136 p3m.sum_q2 = sum_q2;
137 p3m.square_sum_q = square_sum_q;
138 }
139 void adapt_epsilon_elc() override {
140 p3m.params.epsilon = P3M_EPSILON_METALLIC;
141 }
142
143 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
144 [[nodiscard]] bool is_gpu() const noexcept override {
145 return Architecture == Arch::GPU;
146 }
147 [[nodiscard]] bool is_double_precision() const noexcept override {
148 return std::is_same_v<FloatType, double>;
149 }
150
151 void on_activation() override {
152#ifdef CUDA
153 if constexpr (Architecture == Arch::GPU) {
154 request_gpu();
155 }
156#endif
158 tune();
159#ifdef CUDA
160 if constexpr (Architecture == Arch::GPU) {
161 if (is_tuned()) {
163 }
164 }
165#endif
166 }
167
168 double long_range_energy(ParticleRange const &particles) override {
169 return long_range_kernel(false, true, particles);
170 }
171
172 void add_long_range_forces(ParticleRange const &particles) override {
173 if constexpr (Architecture == Arch::CPU) {
174 long_range_kernel(true, false, particles);
175 }
176#ifdef CUDA
177 if constexpr (Architecture == Arch::GPU) {
178 add_long_range_forces_gpu(particles);
179 }
180#endif
181 }
182
183 Utils::Vector9d long_range_pressure(ParticleRange const &particles) override;
184
185 void charge_assign(ParticleRange const &particles) override;
186 void assign_charge(double q, Utils::Vector3d const &real_pos,
187 bool skip_cache) override;
188 void prepare_fft_mesh(bool reset_weights) override {
189 if (reset_weights) {
190 p3m.inter_weights.reset(p3m.params.cao);
191 }
192 p3m.rs_charge_density.resize(Utils::product(p3m.local_mesh.dim));
193 std::ranges::fill(p3m.rs_charge_density, FloatType{});
194 }
195
196protected:
197 /** Compute the k-space part of forces and energies. */
198 double long_range_kernel(bool force_flag, bool energy_flag,
199 ParticleRange const &particles);
200 void calc_influence_function_force() override;
201 void calc_influence_function_energy() override;
202 void scaleby_box_l() override;
203 void init_cpu_kernels();
204#ifdef CUDA
205 void init_gpu_kernels();
206 void add_long_range_forces_gpu(ParticleRange const &particles);
207 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
208 void request_gpu() const;
209#endif
210private:
211 void kernel_ks_charge_density();
212 void kernel_rs_electric_field();
213};
214
215template <typename FloatType, Arch Architecture, typename... Args>
216std::shared_ptr<CoulombP3M> new_coulomb_p3m(P3MParameters &&p3m_params,
217 Args &&...args) {
218 auto state_ptr =
219 std::make_unique<CoulombP3MState<FloatType>>(std::move(p3m_params));
220 auto obj = std::make_shared<CoulombP3MImpl<FloatType, Architecture>>(
221 std::move(state_ptr), std::forward<Args>(args)...);
222 return obj;
223}
224
225#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.
P3M halo communicator.
Definition send_mesh.hpp:38
This file contains the defaults for ESPResSo.
T product(Vector< T, N > const &v)
Definition Vector.hpp:375
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_coulomb_p3m(P3MParameters &&p3m_params, Args &&...args)
Definition p3m.impl.hpp:216
static SteepestDescentParameters params
Currently active steepest descent instance.
void charge_assign(ParticleRange const &particles) override
Definition p3m.cpp:380
double long_range_energy(ParticleRange const &particles) override
Definition p3m.impl.hpp:168
void tune() override
Definition p3m.cpp:913
bool is_gpu() const noexcept override
Definition p3m.impl.hpp:144
bool is_tuned() const noexcept override
Definition p3m.impl.hpp:143
void assign_charge(double q, Utils::Vector3d const &real_pos, bool skip_cache) override
Definition p3m.cpp:392
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
Definition p3m.cpp:183
void add_long_range_forces(ParticleRange const &particles) override
Definition p3m.impl.hpp:172
void count_charged_particles_elc(std::size_t n, double sum_q2, double square_sum_q) override
Definition p3m.impl.hpp:133
void scaleby_box_l() override
Definition p3m.cpp:1003
void calc_influence_function_force() override
Calculate the optimal influence function of .
Definition p3m.cpp:173
Utils::Vector9d long_range_pressure(ParticleRange const &particles) override
Definition p3m.cpp:535
void init_cpu_kernels()
Definition p3m.cpp:293
bool is_double_precision() const noexcept override
Definition p3m.impl.hpp:147
~CoulombP3MImpl() override=default
void on_activation() override
Definition p3m.impl.hpp:151
void count_charged_particles() override
Definition p3m.cpp:144
CoulombP3MImpl(std::unique_ptr< CoulombP3MState< FloatType > > &&p3m_state, double prefactor, int tune_timings, bool tune_verbose, decltype(tune_limits) tune_limits, bool check_complex_residuals)
Definition p3m.impl.hpp:104
void init() override
Definition p3m.impl.hpp:121
CoulombP3MState< FloatType > & p3m
Coulomb P3M parameters.
Definition p3m.impl.hpp:84
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:588
std::shared_ptr< P3MGpuParams > m_gpu_data
Definition p3m.impl.hpp:207
void request_gpu() const
Definition p3m.cpp:1054
void prepare_fft_mesh(bool reset_weights) override
Definition p3m.impl.hpp:188
void init_gpu_kernels()
Definition p3m.cpp:1041
void add_long_range_forces_gpu(ParticleRange const &particles)
Definition p3m.cpp:1017
void adapt_epsilon_elc() override
Definition p3m.impl.hpp:139
p3m_interpolation_cache inter_weights
Definition p3m.impl.hpp:63
std::vector< std::complex< FloatType > > ks_E_fields_storage
Definition p3m.impl.hpp:69
p3m_send_mesh< FloatType > halo_comm
Definition p3m.impl.hpp:71
std::array< std::vector< FloatType >, 3 > rs_E_fields
Definition p3m.impl.hpp:68
double square_sum_q
square of sum of charges.
Definition p3m.impl.hpp:61
std::shared_ptr< P3MFFT< FloatType > > fft
Definition p3m.impl.hpp:72
std::size_t sum_qpart
number of charged particles.
Definition p3m.impl.hpp:57
std::vector< FloatType > rs_charge_density
Definition p3m.impl.hpp:66
double sum_q2
Sum of square of charges.
Definition p3m.impl.hpp:59
std::vector< std::complex< FloatType > > ks_charge_density
Definition p3m.impl.hpp:67
static constexpr auto memory_order
Definition p3m.impl.hpp:54
std::vector< std::complex< FloatType > > rs_E_fields_no_halo
Definition p3m.impl.hpp:70
P3M solver.
Definition p3m.hpp:56
void sanity_checks() const
Definition p3m.hpp:80
Structure to hold P3M parameters and some dependent variables.
State of the p3m methods, the part which applies to both, electrostatic and dipolar p3m.