ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
p3m_heffte.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 "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#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
40#include <Kokkos_Core.hpp>
41#include <omp.h>
42#endif
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, 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, class FFTConfig>
63struct CoulombP3MState : public P3MStateCommon<FloatType> {
64 using P3MStateCommon<FloatType>::P3MStateCommon;
65 using value_type = FloatType;
66 using ComplexType = std::complex<value_type>;
67
68 /** number of charged particles. */
69 std::size_t sum_qpart = 0;
70 /** Sum of square of charges. */
71 double sum_q2 = 0.;
72 /** square of sum of charges. */
73 double square_sum_q = 0.;
74
76
77 /** charge density in real-space with halo */
78 std::vector<FloatType> rs_charge_density;
79 /** charge density in k-space without halo */
80 std::vector<ComplexType> ks_charge_density;
81 /** electric fields in real-space with halo */
82 std::array<std::vector<FloatType>, 3> rs_E_fields;
83 /** electric fields in k-space without halo */
84 std::array<std::vector<ComplexType>, 3> ks_E_fields;
85 /** electric fields in real-space without halo */
86 std::array<std::vector<FloatType>, 3> rs_E_fields_no_halo;
88 std::shared_ptr<P3MFFT<FloatType, FFTConfig>> fft;
89#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
92
93 void init_labels() {
96 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
97 }
98#endif
99};
100
101#ifdef ESPRESSO_CUDA
102struct P3MGpuParams;
103#endif
104
105template <typename FloatType, Arch Architecture, class FFTConfig>
107 ~CoulombP3MHeffte() override = default;
108
110 /** @brief Coulomb P3M parameters. */
112
113private:
114#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
115 // kokkos handle must outlive kokkos data structures from other class members
116 std::shared_ptr<KokkosHandle> m_kokkos_handle;
117#endif
118 std::unique_ptr<CoulombP3MStateClass> p3m_state_ptr;
119 TuningParameters tuning;
120 bool m_is_tuned;
121
122 constexpr const Utils::Vector3i get_memory_layout() const {
123 auto constexpr memory_order = CoulombP3MStateClass::memory_order;
125 return {2, 1, 0};
126 }
127 return {0, 1, 2};
128 }
129
130public:
131 CoulombP3MHeffte(std::unique_ptr<CoulombP3MStateClass> &&p3m_state,
133 : CoulombP3M(p3m_state->params), p3m{*p3m_state},
135 m_kokkos_handle{::kokkos_handle},
136#endif
137 p3m_state_ptr{std::move(p3m_state)}, tuning{std::move(tuning_params)} {
138
139 if (tuning.timings <= 0) {
140 throw std::domain_error("Parameter 'timings' must be > 0");
141 }
142 m_is_tuned = not p3m.params.tuning;
143 p3m.params.tuning = false;
145#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
147#endif
148 }
149
150 void init() override {
151 if constexpr (Architecture == Arch::CPU) {
153 }
154#ifdef ESPRESSO_CUDA
155 if constexpr (Architecture == Arch::CUDA) {
157 }
158#endif
159 }
160 void tune() override;
161 void count_charged_particles() override;
162 void count_charged_particles_elc(std::size_t n, double sum_q2,
163 double square_sum_q) override {
164 p3m.sum_qpart = n;
165 p3m.sum_q2 = sum_q2;
166 p3m.square_sum_q = square_sum_q;
167 }
171
172 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
173 [[nodiscard]] bool is_gpu() const noexcept override {
174 return Architecture != Arch::CPU;
175 }
177 return std::is_same_v<FloatType, double>;
178 }
179
180 void on_activation() override {
181#ifdef ESPRESSO_CUDA
182 if constexpr (Architecture == Arch::CUDA) {
183 request_gpu();
184 }
185#endif
187 tune();
188#ifdef ESPRESSO_CUDA
189 if constexpr (Architecture == Arch::CUDA) {
190 if (is_tuned()) {
192 }
193 }
194#endif
195 }
196
197 double long_range_energy() override { return long_range_kernel(false, true); }
198
199 void add_long_range_forces() override {
200 if constexpr (Architecture == Arch::CPU) {
201 long_range_kernel(true, false);
202 }
203#ifdef ESPRESSO_CUDA
204 if constexpr (Architecture == Arch::CUDA) {
206 }
207#endif
208 }
209
211
212 void charge_assign() override;
213 void assign_charge(double q, Utils::Vector3d const &real_pos,
214 bool skip_cache) override;
215 void prepare_fft_mesh(bool reset_weights) override {
216 if (reset_weights) {
218 }
220#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
221 using execution_space = Kokkos::DefaultExecutionSpace;
222 auto const num_threads = execution_space().concurrency();
223 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
225 Kokkos::deep_copy(p3m.rs_charge_density_kokkos, FloatType{0});
226#endif // ESPRESSO_SHARED_MEMORY_PARALLELISM
227 std::ranges::fill(p3m.rs_charge_density, FloatType{0});
228 }
229
230protected:
231 /** Compute the k-space part of forces and energies. */
232 double long_range_kernel(bool force_flag, bool energy_flag);
233 void calc_influence_function_force() override;
234 void calc_influence_function_energy() override;
235 void scaleby_box_l() override;
236 void init_cpu_kernels();
237#ifdef ESPRESSO_CUDA
238 void init_gpu_kernels();
240 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
241 void request_gpu() const;
242#endif
243private:
244 void kernel_ks_charge_density();
245 void kernel_rs_electric_field();
246};
247
248#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:38
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
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.
double long_range_energy() override
void adapt_epsilon_elc() override
void tune() override
void count_charged_particles_elc(std::size_t n, double sum_q2, double square_sum_q) override
std::shared_ptr< P3MGpuParams > m_gpu_data
void assign_charge(double q, Utils::Vector3d const &real_pos, bool skip_cache) override
double long_range_kernel(bool force_flag, bool energy_flag)
Compute the k-space part of forces and energies.
void init() override
bool is_gpu() const noexcept override
void charge_assign() override
void on_activation() override
~CoulombP3MHeffte() override=default
void count_charged_particles() override
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
CoulombP3MHeffte(std::unique_ptr< CoulombP3MStateClass > &&p3m_state, TuningParameters tuning_params, double prefactor)
CoulombP3MStateClass & p3m
Coulomb P3M parameters.
bool is_tuned() const noexcept override
Utils::Vector9d long_range_pressure() override
void add_long_range_forces() override
bool is_double_precision() const noexcept override
void calc_influence_function_force() override
Calculate the optimal influence function of .
void prepare_fft_mesh(bool reset_weights) override
void scaleby_box_l() override
Base class for the electrostatics P3M algorithm.
std::size_t sum_qpart
number of charged particles.
std::array< std::vector< FloatType >, 3 > rs_E_fields_no_halo
electric fields in real-space without halo
FloatType value_type
std::complex< value_type > ComplexType
std::array< std::vector< FloatType >, 3 > rs_E_fields
electric fields in real-space with halo
double square_sum_q
square of sum of charges.
Kokkos::View< FloatType **, Kokkos::LayoutRight, Kokkos::HostSpace > rs_charge_density_kokkos
std::vector< FloatType > rs_charge_density
charge density in real-space with halo
std::shared_ptr< P3MFFT< FloatType, FFTConfig > > fft
p3m_send_mesh< FloatType > halo_comm
double sum_q2
Sum of square of charges.
std::vector< ComplexType > ks_charge_density
charge density in k-space without halo
std::array< std::vector< ComplexType >, 3 > ks_E_fields
electric fields in k-space without halo
p3m_interpolation_cache inter_weights
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.
P3MParameters params
P3M base parameters.
P3MLocalMesh local_mesh
Local mesh geometry information for this MPI rank.