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#include <Kokkos_Core.hpp>
40#include <omp.h>
41
42#include <algorithm>
43#include <array>
44#include <cassert>
45#include <complex>
46#include <cstddef>
47#include <memory>
48#include <stdexcept>
49#include <type_traits>
50#include <utility>
51#include <vector>
52
53template <typename FloatType, Arch Architecture, class FFTConfig> class P3MFFT;
54
55/**
56 * @brief Base class for the electrostatics P3M algorithm.
57 * Contains a handle to the FFT backend, information about the local
58 * mesh, the differential operator, and various buffers.
59 */
60template <typename FloatType, Arch Architecture, class FFTConfig>
61struct CoulombP3MState : public P3MStateCommon<FloatType, Architecture> {
63 using value_type = FloatType;
64 using ComplexType = std::complex<value_type>;
65 using memory_space = Kokkos::HostSpace;
66 using execution_space = Kokkos::DefaultHostExecutionSpace;
67 using r_space_layout = FFTConfig::r_space_layout;
68 using k_space_layout = FFTConfig::k_space_layout;
69
70 /** number of charged particles. */
71 std::size_t sum_qpart = 0;
72 /** Sum of square of charges. */
73 double sum_q2 = 0.;
74 /** square of sum of charges. */
75 double square_sum_q = 0.;
76
78
79 /** charge density in real-space with halo */
80 std::vector<FloatType> rs_charge_density;
81 /** charge density in k-space without halo */
82 std::vector<ComplexType> ks_charge_density;
83 /** electric fields in real-space with halo */
84 std::array<std::vector<FloatType>, 3> rs_E_fields;
85 /** electric fields in k-space without halo */
86 std::array<std::vector<ComplexType>, 3> ks_E_fields;
87 /** electric fields in real-space without halo */
88 std::array<std::vector<FloatType>, 3> rs_E_fields_no_halo;
90 std::array<std::shared_ptr<P3MFFT<FloatType, Arch::CPU, FFTConfig>>, 3> ffts;
91 std::shared_ptr<P3MFFT<FloatType, Arch::CPU, FFTConfig>> fft;
92 Kokkos::View<FloatType **, r_space_layout, Kokkos::HostSpace>
94
95 void init_labels() {
98 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
99 }
100};
101
102#ifdef ESPRESSO_CUDA
103struct P3MGpuParams;
104#endif
105
106template <typename FloatType, Arch Architecture, class FFTConfig>
108 ~CoulombP3MHeffte() override = default;
109
112 /** @brief Coulomb P3M parameters. */
114
115private:
116 // kokkos handle must outlive kokkos data structures from other class members
117 std::shared_ptr<KokkosHandle> m_kokkos_handle;
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},
134 m_kokkos_handle{::kokkos_handle}, p3m_state_ptr{std::move(p3m_state)},
135 tuning{std::move(tuning_params)} {
136
137 if (tuning.timings <= 0) {
138 throw std::domain_error("Parameter 'timings' must be > 0");
139 }
140 m_is_tuned = not p3m.params.tuning;
141 p3m.params.tuning = false;
144 }
145
146 void init() override {
147 if constexpr (Architecture == Arch::CPU) {
149 }
150#ifdef ESPRESSO_CUDA
151 if constexpr (Architecture == Arch::CUDA) {
153 }
154#endif
155 }
156 void tune() override;
157 void count_charged_particles() override;
158 void count_charged_particles_elc(std::size_t n, double sum_q2,
159 double square_sum_q) override {
160 p3m.sum_qpart = n;
161 p3m.sum_q2 = sum_q2;
162 p3m.square_sum_q = square_sum_q;
163 }
167
168 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
169 [[nodiscard]] bool is_gpu() const noexcept override {
170 return Architecture != Arch::CPU;
171 }
173 return std::is_same_v<FloatType, double>;
174 }
175
176 void on_activation() override {
177#ifdef ESPRESSO_CUDA
178 if constexpr (Architecture == Arch::CUDA) {
179 request_gpu();
180 }
181#endif
183 tune();
184#ifdef ESPRESSO_CUDA
185 if constexpr (Architecture == Arch::CUDA) {
186 if (is_tuned()) {
188 }
189 }
190#endif
191 }
192
193 double long_range_energy() override { return long_range_kernel(false, true); }
194
195 void add_long_range_forces() override {
196 if constexpr (Architecture == Arch::CPU) {
197 long_range_kernel(true, false);
198 }
199#ifdef ESPRESSO_CUDA
200 if constexpr (Architecture == Arch::CUDA) {
202 }
203#endif
204 }
205
207
208 void charge_assign() override;
209 void assign_charge(double q, Utils::Vector3d const &real_pos,
210 bool skip_cache) override;
211 void prepare_fft_mesh(bool reset_weights) override {
212 if (reset_weights) {
214 }
216 using execution_space = Kokkos::DefaultHostExecutionSpace;
217 auto const num_threads = execution_space().concurrency();
218 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
220 Kokkos::deep_copy(p3m.rs_charge_density_kokkos, FloatType{0});
221 std::ranges::fill(p3m.rs_charge_density, FloatType{0});
222 }
223
224protected:
225 /** Compute the k-space part of forces and energies. */
226 double long_range_kernel(bool force_flag, bool energy_flag);
227 void calc_influence_function_force() override;
228 void calc_influence_function_energy() override;
229 void scaleby_box_l() override;
230 void init_cpu_kernels();
231#ifdef ESPRESSO_CUDA
232 void init_gpu_kernels();
234 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
235 void request_gpu() const;
236#endif
237private:
238 void kernel_ks_charge_density();
239 void kernel_rs_electric_field();
240};
241
242#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:46
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.
Kokkos::DefaultHostExecutionSpace execution_space
Kokkos::View< FloatType **, r_space_layout, Kokkos::HostSpace > rs_charge_density_kokkos
std::array< std::vector< FloatType >, 3 > rs_E_fields_no_halo
electric fields in real-space without halo
std::vector< FloatType > rs_charge_density
charge density in real-space with halo
FFTConfig::r_space_layout r_space_layout
std::array< std::shared_ptr< P3MFFT< FloatType, Arch::CPU, FFTConfig > >, 3 > ffts
Kokkos::HostSpace memory_space
std::vector< ComplexType > ks_charge_density
charge density in k-space without halo
std::array< std::vector< FloatType >, 3 > rs_E_fields
electric fields in real-space with halo
std::shared_ptr< P3MFFT< FloatType, Arch::CPU, FFTConfig > > fft
FFTConfig::k_space_layout k_space_layout
std::array< std::vector< ComplexType >, 3 > ks_E_fields
electric fields in k-space without halo
p3m_interpolation_cache inter_weights
FloatType value_type
double square_sum_q
square of sum of charges.
std::complex< value_type > ComplexType
std::size_t sum_qpart
number of charged particles.
p3m_send_mesh< FloatType > halo_comm
double sum_q2
Sum of square of charges.
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.