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-2026 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 ESPRESSO_P3M
27
29
30#include "communication.hpp"
31#include "kokkos_helpers.hpp"
32#include "p3m/P3MFFTBackend.hpp"
33#include "p3m/common.hpp"
34#include "p3m/data_struct.hpp"
35#include "p3m/interpolation.hpp"
36#include "p3m/send_mesh.hpp"
37
38#include <utils/Vector.hpp>
39#include <utils/index.hpp>
40
41#include <Kokkos_Core.hpp>
42#include <omp.h>
43
44#include <algorithm>
45#include <array>
46#include <cassert>
47#include <complex>
48#include <cstddef>
49#include <memory>
50#include <stdexcept>
51#include <type_traits>
52#include <utility>
53#include <vector>
54
55template <typename FloatType, Arch Architecture, class FFTConfig> class P3MFFT;
56
57/**
58 * @brief Base class for the electrostatics P3M algorithm.
59 * Contains a handle to the FFT backend, information about the local
60 * mesh, the differential operator, and various buffers.
61 */
62template <typename FloatType, Arch Architecture, class FFTConfig>
63struct CoulombP3MState : public P3MStateCommon<FloatType, Architecture> {
65 using value_type = FloatType;
66 using ComplexType = std::complex<value_type>;
67 using memory_space = Kokkos::HostSpace;
68 using execution_space = Kokkos::DefaultHostExecutionSpace;
69 using r_space_layout = FFTConfig::r_space_layout;
70 using k_space_layout = FFTConfig::k_space_layout;
71
72 /** number of charged particles. */
73 std::size_t sum_qpart = 0;
74 /** Sum of square of charges. */
75 double sum_q2 = 0.;
76 /** square of sum of charges. */
77 double square_sum_q = 0.;
78
80
81 /** charge density in real-space with halo */
82 std::vector<FloatType> rs_charge_density;
83 /** charge density in k-space without halo */
84 std::vector<ComplexType> ks_charge_density;
85 /** electric fields in real-space with halo */
86 std::array<std::vector<FloatType>, 3> rs_E_fields;
87 /** electric fields in k-space without halo */
88 std::array<std::vector<ComplexType>, 3> ks_E_fields;
89 /** electric fields in real-space without halo */
90 std::array<std::vector<FloatType>, 3> rs_E_fields_no_halo;
92 // FFT reciprocal-space transform, hidden behind the backend interface so the
93 // solver is agnostic to heFFTe vs kokkos-fft (see init_cpu_kernels).
94 std::shared_ptr<P3MFFTBackend<FloatType, FFTConfig>> fft;
95 Kokkos::View<FloatType **, r_space_layout, Kokkos::HostSpace>
97
98 void init_labels() {
101 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
102 }
103};
104
105#ifdef ESPRESSO_CUDA
106struct P3MGpuParams;
107#endif
108
109template <typename FloatType, Arch Architecture, class FFTConfig>
110struct CoulombP3MImpl : public CoulombP3M {
111 ~CoulombP3MImpl() override = default;
112
115 /** @brief Coulomb P3M parameters. */
117
118private:
119 // kokkos handle must outlive kokkos data structures from other class members
120 std::shared_ptr<KokkosHandle> m_kokkos_handle;
121 std::unique_ptr<CoulombP3MStateClass> p3m_state_ptr;
122 TuningParameters tuning;
123 bool m_is_tuned;
124
125 constexpr const Utils::Vector3i get_memory_layout() const {
126 auto constexpr memory_order = CoulombP3MStateClass::memory_order;
128 return {2, 1, 0};
129 }
130 return {0, 1, 2};
131 }
132
133public:
134 CoulombP3MImpl(std::unique_ptr<CoulombP3MStateClass> &&p3m_state,
136 : CoulombP3M(p3m_state->params), p3m{*p3m_state},
137 m_kokkos_handle{::kokkos_handle}, p3m_state_ptr{std::move(p3m_state)},
138 tuning{std::move(tuning_params)} {
139
140 if (tuning.timings <= 0) {
141 throw std::domain_error("Parameter 'timings' must be > 0");
142 }
143 m_is_tuned = not p3m.params.tuning;
144 p3m.params.tuning = false;
147 }
148
149 void init() override {
150 if constexpr (Architecture == Arch::CPU) {
152 }
153#ifdef ESPRESSO_CUDA
154 if constexpr (Architecture == Arch::CUDA) {
156 }
157#endif
158 }
159 void tune() override;
160 void count_charged_particles() override;
161 void count_charged_particles_elc(std::size_t n, double sum_q2,
162 double square_sum_q) override {
163 p3m.sum_qpart = n;
164 p3m.sum_q2 = sum_q2;
165 p3m.square_sum_q = square_sum_q;
166 }
170
171 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
172 [[nodiscard]] bool is_gpu() const noexcept override {
173 return Architecture != Arch::CPU;
174 }
176 return std::is_same_v<FloatType, double>;
177 }
178
179 void on_activation() override {
180#ifdef ESPRESSO_CUDA
181 if constexpr (Architecture == Arch::CUDA) {
182 request_gpu();
183 }
184#endif
186 tune();
187#ifdef ESPRESSO_CUDA
188 if constexpr (Architecture == Arch::CUDA) {
189 if (is_tuned()) {
191 }
192 }
193#endif
194 }
195
196 double long_range_energy() override { return long_range_kernel(false, true); }
197
198 void add_long_range_forces() override {
199 if constexpr (Architecture == Arch::CPU) {
200 long_range_kernel(true, false);
201 }
202#ifdef ESPRESSO_CUDA
203 if constexpr (Architecture == Arch::CUDA) {
205 }
206#endif
207 }
208
210
211 void charge_assign() override;
212 void assign_charge(double q, Utils::Vector3d const &real_pos,
213 bool skip_cache) override;
214 void prepare_fft_mesh(bool reset_weights) override {
215 if (reset_weights) {
217 }
219 using execution_space = Kokkos::DefaultHostExecutionSpace;
220 auto const num_threads = execution_space().concurrency();
221 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
224 FloatType{0});
225 std::ranges::fill(p3m.rs_charge_density, FloatType{0});
226 }
227
228protected:
229 /** Compute the k-space part of forces and energies. */
230 double long_range_kernel(bool force_flag, bool energy_flag);
231 void calc_influence_function_force() override;
232 void calc_influence_function_energy() override;
233 void scaleby_box_l() override;
234 void init_cpu_kernels();
235#ifdef ESPRESSO_CUDA
236 void init_gpu_kernels();
238 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
239 void request_gpu() const;
240#endif
241private:
242 void kernel_ks_charge_density();
243 void kernel_rs_electric_field();
244};
245
246#endif // ESPRESSO_P3M
Vector implementation and trait types for boost qvm interoperability.
void set_prefactor(double new_prefactor)
double prefactor
Electrostatics prefactor.
FFT manager.
Definition P3MFFT.hpp:48
Cache for interpolation weights.
void reset(int cao)
Reset the cache.
P3M halo communicator.
Definition send_mesh.hpp:38
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
std::shared_ptr< KokkosHandle > kokkos_handle
ESPRESSO_ATTR_ALWAYS_INLINE void kokkos_deep_copy(auto const &exec_space, auto const &view, auto const &value)
Wrapper for Kokkos::deep_copy that skips fork/join when the number of threads is 1.
STL namespace.
Common functions for dipolar and charge P3M.
auto constexpr P3M_EPSILON_METALLIC
This value indicates metallic boundary conditions.
P3M algorithm for long-range Coulomb interaction.
~CoulombP3MImpl() override=default
void count_charged_particles() override
bool is_tuned() const noexcept override
Definition p3m.impl.hpp:171
bool is_gpu() const noexcept override
Definition p3m.impl.hpp:172
void add_long_range_forces() override
Definition p3m.impl.hpp:198
CoulombP3MStateClass & p3m
Coulomb P3M parameters.
Definition p3m.impl.hpp:116
void init() override
Definition p3m.impl.hpp:149
CoulombP3MImpl(std::unique_ptr< CoulombP3MStateClass > &&p3m_state, TuningParameters tuning_params, double prefactor)
Definition p3m.impl.hpp:134
void charge_assign() override
double long_range_energy() override
Definition p3m.impl.hpp:196
double long_range_kernel(bool force_flag, bool energy_flag)
Compute the k-space part of forces and energies.
Utils::Vector9d long_range_pressure() override
void scaleby_box_l() override
void calc_influence_function_force() override
Calculate the optimal influence function of .
void prepare_fft_mesh(bool reset_weights) override
Definition p3m.impl.hpp:214
void count_charged_particles_elc(std::size_t n, double sum_q2, double square_sum_q) override
Definition p3m.impl.hpp:161
void assign_charge(double q, Utils::Vector3d const &real_pos, bool skip_cache) override
std::shared_ptr< P3MGpuParams > m_gpu_data
Definition p3m.impl.hpp:238
bool is_double_precision() const noexcept override
Definition p3m.impl.hpp:175
void adapt_epsilon_elc() override
Definition p3m.impl.hpp:167
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
void on_activation() override
Definition p3m.impl.hpp:179
Base class for the electrostatics P3M algorithm.
Definition p3m.impl.hpp:63
Kokkos::DefaultHostExecutionSpace execution_space
Definition p3m.impl.hpp:68
Kokkos::View< FloatType **, r_space_layout, Kokkos::HostSpace > rs_charge_density_kokkos
Definition p3m.impl.hpp:96
std::array< std::vector< FloatType >, 3 > rs_E_fields_no_halo
electric fields in real-space without halo
Definition p3m.impl.hpp:90
std::vector< FloatType > rs_charge_density
charge density in real-space with halo
Definition p3m.impl.hpp:82
std::shared_ptr< P3MFFTBackend< FloatType, FFTConfig > > fft
Definition p3m.impl.hpp:94
FFTConfig::r_space_layout r_space_layout
Definition p3m.impl.hpp:69
Kokkos::HostSpace memory_space
Definition p3m.impl.hpp:67
std::vector< ComplexType > ks_charge_density
charge density in k-space without halo
Definition p3m.impl.hpp:84
std::array< std::vector< FloatType >, 3 > rs_E_fields
electric fields in real-space with halo
Definition p3m.impl.hpp:86
FFTConfig::k_space_layout k_space_layout
Definition p3m.impl.hpp:70
std::array< std::vector< ComplexType >, 3 > ks_E_fields
electric fields in k-space without halo
Definition p3m.impl.hpp:88
p3m_interpolation_cache inter_weights
Definition p3m.impl.hpp:79
FloatType value_type
Definition p3m.impl.hpp:65
double square_sum_q
square of sum of charges.
Definition p3m.impl.hpp:77
std::complex< value_type > ComplexType
Definition p3m.impl.hpp:66
void init_labels()
Definition p3m.impl.hpp:98
std::size_t sum_qpart
number of charged particles.
Definition p3m.impl.hpp:73
p3m_send_mesh< FloatType > halo_comm
Definition p3m.impl.hpp:91
double sum_q2
Sum of square of charges.
Definition p3m.impl.hpp:75
P3M solver.
Definition p3m.hpp:55
void sanity_checks() const
Definition p3m.hpp:79
std::size_t size
number of local mesh points including halo layers.
int cao
charge assignment order ([0,7]).
bool tuning
tuning or production?
double epsilon
epsilon of the "surrounding dielectric".
State of the p3m methods, the part which applies to both, electrostatic and dipolar p3m.
P3MLocalMesh local_mesh
Local mesh geometry information for this MPI rank.
P3MParameters params
P3M base parameters.