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 "ParticleRange.hpp"
31#include "communication.hpp"
32#include "p3m/common.hpp"
33#include "p3m/data_struct.hpp"
34#include "p3m/interpolation.hpp"
35#include "p3m/send_mesh.hpp"
36
37#include <utils/Vector.hpp>
38#include <utils/index.hpp>
39
40#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
41#include <Kokkos_Core.hpp>
42#include <omp.h>
43#endif
44
45#include <algorithm>
46#include <complex>
47#include <cstddef>
48#include <memory>
49#include <optional>
50#include <stdexcept>
51#include <type_traits>
52#include <utility>
53
54template <typename FloatType, class FFTConfig> class P3MFFT;
55
56/**
57 * @brief Base class for the electrostatics P3M algorithm.
58 * Contains a handle to the FFT backend, information about the local
59 * mesh, the differential operator, and various buffers.
60 */
61template <typename FloatType, class FFTConfig>
62struct CoulombP3MState : public P3MStateCommon<FloatType> {
63 using P3MStateCommon<FloatType>::P3MStateCommon;
64 using value_type = FloatType;
65 using ComplexType = std::complex<value_type>;
66
67 /** number of charged particles. */
68 std::size_t sum_qpart = 0;
69 /** Sum of square of charges. */
70 double sum_q2 = 0.;
71 /** square of sum of charges. */
72 double square_sum_q = 0.;
73
75
76 /** charge density in real-space with halo */
77 std::vector<FloatType> rs_charge_density;
78 /** charge density in k-space without halo */
79 std::vector<ComplexType> ks_charge_density;
80 /** electric fields in real-space with halo */
81 std::array<std::vector<FloatType>, 3> rs_E_fields;
82 /** electric fields in k-space without halo */
83 std::array<std::vector<ComplexType>, 3> ks_E_fields;
84 /** electric fields in real-space without halo */
85 std::array<std::vector<FloatType>, 3> rs_E_fields_no_halo;
87 std::shared_ptr<P3MFFT<FloatType, FFTConfig>> fft;
88#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
91
92 void init_labels() {
95 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
96 }
97#endif
98};
99
100#ifdef ESPRESSO_CUDA
101struct P3MGpuParams;
102#endif
103
104template <typename FloatType, Arch Architecture, class FFTConfig>
106 ~CoulombP3MHeffte() override = default;
107
109 /** @brief Coulomb P3M parameters. */
111
112private:
113#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
114 // kokkos handle must outlive kokkos data structures from other class members
115 std::shared_ptr<KokkosHandle> m_kokkos_handle;
116#endif
117 std::unique_ptr<CoulombP3MStateClass> p3m_state_ptr;
118 TuningParameters tuning;
119 bool m_is_tuned;
120
121 constexpr const Utils::Vector3i get_memory_layout() const {
122 auto constexpr memory_order = CoulombP3MStateClass::memory_order;
124 return {2, 1, 0};
125 }
126 return {0, 1, 2};
127 }
128
129public:
130 CoulombP3MHeffte(std::unique_ptr<CoulombP3MStateClass> &&p3m_state,
134 m_kokkos_handle{::kokkos_handle},
135#endif
136 p3m_state_ptr{std::move(p3m_state)}, tuning{std::move(tuning_params)} {
137
138 if (tuning.timings <= 0) {
139 throw std::domain_error("Parameter 'timings' must be > 0");
140 }
141 m_is_tuned = not p3m.params.tuning;
142 p3m.params.tuning = false;
144#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
146#endif
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(ParticleRange const &particles) override {
197 return long_range_kernel(false, true, particles);
198 }
199
200 void add_long_range_forces(ParticleRange const &particles) override {
201 if constexpr (Architecture == Arch::CPU) {
202 long_range_kernel(true, false, particles);
203 }
204#ifdef ESPRESSO_CUDA
205 if constexpr (Architecture == Arch::CUDA) {
206 add_long_range_forces_gpu(particles);
207 }
208#endif
209 }
210
211 Utils::Vector9d long_range_pressure(ParticleRange const &particles) override;
212
213 void charge_assign(ParticleRange const &particles) override;
214 void assign_charge(double q, Utils::Vector3d const &real_pos,
215 bool skip_cache) override;
216 void prepare_fft_mesh(bool reset_weights) override {
217 if (reset_weights) {
219 }
221#ifdef ESPRESSO_SHARED_MEMORY_PARALLELISM
222 using execution_space = Kokkos::DefaultExecutionSpace;
223 auto const num_threads = execution_space().concurrency();
224 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
226 Kokkos::deep_copy(p3m.rs_charge_density_kokkos, FloatType{0});
227#endif // ESPRESSO_SHARED_MEMORY_PARALLELISM
228 std::ranges::fill(p3m.rs_charge_density, FloatType{0});
229 }
230
231protected:
232 /** Compute the k-space part of forces and energies. */
233 double long_range_kernel(bool force_flag, bool energy_flag,
234 ParticleRange const &particles);
235 void calc_influence_function_force() override;
236 void calc_influence_function_energy() override;
237 void scaleby_box_l() override;
238 void init_cpu_kernels();
239#ifdef ESPRESSO_CUDA
240 void init_gpu_kernels();
241 void add_long_range_forces_gpu(ParticleRange const &particles);
242 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
243 void request_gpu() const;
244#endif
245private:
246 void kernel_ks_charge_density();
247 void kernel_rs_electric_field();
248};
249
250#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
A range of particles.
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.
static SteepestDescentParameters params
Currently active steepest descent instance.
void adapt_epsilon_elc() override
void tune() override
void charge_assign(ParticleRange const &particles) 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
void init() override
bool is_gpu() const noexcept override
double long_range_kernel(bool force_flag, bool energy_flag, ParticleRange const &particles)
Compute the k-space part of forces and energies.
void on_activation() override
~CoulombP3MHeffte() override=default
void count_charged_particles() override
double long_range_energy(ParticleRange const &particles) override
void calc_influence_function_energy() override
Calculate the influence function optimized for the energy and the self energy correction.
void add_long_range_forces(ParticleRange const &particles) override
CoulombP3MHeffte(std::unique_ptr< CoulombP3MStateClass > &&p3m_state, TuningParameters tuning_params, double prefactor)
CoulombP3MStateClass & p3m
Coulomb P3M parameters.
bool is_tuned() const noexcept override
bool is_double_precision() const noexcept override
void calc_influence_function_force() override
Calculate the optimal influence function of .
void add_long_range_forces_gpu(ParticleRange const &particles)
Utils::Vector9d long_range_pressure(ParticleRange const &particles) override
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:57
void sanity_checks() const
Definition p3m.hpp:81
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.