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-2025 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 <complex>
46#include <cstddef>
47#include <memory>
48#include <optional>
49#include <stdexcept>
50#include <type_traits>
51#include <utility>
52
53template <typename FloatType, 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, class FFTConfig>
61struct CoulombP3MState : public P3MStateCommon<FloatType> {
62 using P3MStateCommon<FloatType>::P3MStateCommon;
63 using value_type = FloatType;
64 using ComplexType = std::complex<value_type>;
65
66 /** number of charged particles. */
67 std::size_t sum_qpart = 0;
68 /** Sum of square of charges. */
69 double sum_q2 = 0.;
70 /** square of sum of charges. */
71 double square_sum_q = 0.;
72
74
75 /** charge density in real-space with halo */
76 std::vector<FloatType> rs_charge_density;
77 /** charge density in k-space without halo */
78 std::vector<ComplexType> ks_charge_density;
79 /** electric fields in real-space with halo */
80 std::array<std::vector<FloatType>, 3> rs_E_fields;
81 /** electric fields in k-space without halo */
82 std::array<std::vector<ComplexType>, 3> ks_E_fields;
83 /** electric fields in real-space without halo */
84 std::array<std::vector<FloatType>, 3> rs_E_fields_no_halo;
86 std::shared_ptr<P3MFFT<FloatType, FFTConfig>> fft;
87#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
90
91 void init_labels() {
92 assert(rs_charge_density.empty());
94 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
95 }
96#endif
97};
98
99#ifdef ESPRESSO_CUDA
100struct P3MGpuParams;
101#endif
102
103template <typename FloatType, Arch Architecture, class FFTConfig>
105 ~CoulombP3MHeffte() override = default;
106
108 /** @brief Coulomb P3M parameters. */
110
111private:
112#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
113 // kokkos handle must outlive kokkos data structures from other class members
114 std::shared_ptr<KokkosHandle> m_kokkos_handle;
115#endif
116 std::unique_ptr<CoulombP3MStateClass> p3m_state_ptr;
117 TuningParameters tuning;
118 bool m_is_tuned;
119
120 constexpr const Utils::Vector3i get_memory_layout() const {
121 auto constexpr memory_order = CoulombP3MStateClass::memory_order;
122 if constexpr (memory_order == Utils::MemoryOrder::COLUMN_MAJOR) {
123 return {2, 1, 0};
124 }
125 return {0, 1, 2};
126 }
127
128public:
129 CoulombP3MHeffte(std::unique_ptr<CoulombP3MStateClass> &&p3m_state,
130 TuningParameters tuning_params, double prefactor)
131 : CoulombP3M(p3m_state->params), p3m{*p3m_state},
132#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
133 m_kokkos_handle{::kokkos_handle},
134#endif
135 p3m_state_ptr{std::move(p3m_state)}, 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;
143#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
145#endif
146 }
147
148 void init() override {
149 if constexpr (Architecture == Arch::CPU) {
151 }
152#ifdef ESPRESSO_CUDA
153 if constexpr (Architecture == Arch::CUDA) {
155 }
156#endif
157 }
158 void tune() override;
159 void count_charged_particles() override;
160 void count_charged_particles_elc(std::size_t n, double sum_q2,
161 double square_sum_q) override {
162 p3m.sum_qpart = n;
163 p3m.sum_q2 = sum_q2;
164 p3m.square_sum_q = square_sum_q;
165 }
169
170 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
171 [[nodiscard]] bool is_gpu() const noexcept override {
172 return Architecture != Arch::CPU;
173 }
174 [[nodiscard]] bool is_double_precision() const noexcept override {
175 return std::is_same_v<FloatType, double>;
176 }
177
178 void on_activation() override {
179#ifdef ESPRESSO_CUDA
180 if constexpr (Architecture == Arch::CUDA) {
181 request_gpu();
182 }
183#endif
185 tune();
186#ifdef ESPRESSO_CUDA
187 if constexpr (Architecture == Arch::CUDA) {
188 if (is_tuned()) {
190 }
191 }
192#endif
193 }
194
195 double long_range_energy() override { return long_range_kernel(false, true); }
196
197 void add_long_range_forces() override {
198 if constexpr (Architecture == Arch::CPU) {
199 long_range_kernel(true, false);
200 }
201#ifdef ESPRESSO_CUDA
202 if constexpr (Architecture == Arch::CUDA) {
204 }
205#endif
206 }
207
209
210 void charge_assign() override;
211 void assign_charge(double q, Utils::Vector3d const &real_pos,
212 bool skip_cache) override;
213 void prepare_fft_mesh(bool reset_weights) override {
214 if (reset_weights) {
216 }
218#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
219 using execution_space = Kokkos::DefaultExecutionSpace;
220 auto const num_threads = execution_space().concurrency();
221 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
222 num_threads, p3m.local_mesh.size);
223 Kokkos::deep_copy(p3m.rs_charge_density_kokkos, FloatType{0});
224#endif // ESPRESSO_SHARED_MEMORY_PARALLELISM
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:38
Cache for interpolation weights.
void reset(int cao)
Reset the cache.
P3M halo communicator.
Definition send_mesh.hpp:38
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.