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, 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;
89
90 void init_labels() {
91 assert(rs_charge_density.empty());
93 "CoulombP3MState::rs_charge_density_kokkos", 0, 0);
94 }
95};
96
97#ifdef ESPRESSO_CUDA
98struct P3MGpuParams;
99#endif
100
101template <typename FloatType, Arch Architecture, class FFTConfig>
103 ~CoulombP3MHeffte() override = default;
104
106 /** @brief Coulomb P3M parameters. */
108
109private:
110 // kokkos handle must outlive kokkos data structures from other class members
111 std::shared_ptr<KokkosHandle> m_kokkos_handle;
112 std::unique_ptr<CoulombP3MStateClass> p3m_state_ptr;
113 TuningParameters tuning;
114 bool m_is_tuned;
115
116 constexpr const Utils::Vector3i get_memory_layout() const {
117 auto constexpr memory_order = CoulombP3MStateClass::memory_order;
118 if constexpr (memory_order == Utils::MemoryOrder::COLUMN_MAJOR) {
119 return {2, 1, 0};
120 }
121 return {0, 1, 2};
122 }
123
124public:
125 CoulombP3MHeffte(std::unique_ptr<CoulombP3MStateClass> &&p3m_state,
126 TuningParameters tuning_params, double prefactor)
127 : CoulombP3M(p3m_state->params), p3m{*p3m_state},
128 m_kokkos_handle{::kokkos_handle}, p3m_state_ptr{std::move(p3m_state)},
129 tuning{std::move(tuning_params)} {
130
131 if (tuning.timings <= 0) {
132 throw std::domain_error("Parameter 'timings' must be > 0");
133 }
134 m_is_tuned = not p3m.params.tuning;
135 p3m.params.tuning = false;
138 }
139
140 void init() override {
141 if constexpr (Architecture == Arch::CPU) {
143 }
144#ifdef ESPRESSO_CUDA
145 if constexpr (Architecture == Arch::CUDA) {
147 }
148#endif
149 }
150 void tune() override;
151 void count_charged_particles() override;
152 void count_charged_particles_elc(std::size_t n, double sum_q2,
153 double square_sum_q) override {
154 p3m.sum_qpart = n;
155 p3m.sum_q2 = sum_q2;
156 p3m.square_sum_q = square_sum_q;
157 }
161
162 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
163 [[nodiscard]] bool is_gpu() const noexcept override {
164 return Architecture != Arch::CPU;
165 }
166 [[nodiscard]] bool is_double_precision() const noexcept override {
167 return std::is_same_v<FloatType, double>;
168 }
169
170 void on_activation() override {
171#ifdef ESPRESSO_CUDA
172 if constexpr (Architecture == Arch::CUDA) {
173 request_gpu();
174 }
175#endif
177 tune();
178#ifdef ESPRESSO_CUDA
179 if constexpr (Architecture == Arch::CUDA) {
180 if (is_tuned()) {
182 }
183 }
184#endif
185 }
186
187 double long_range_energy() override { return long_range_kernel(false, true); }
188
189 void add_long_range_forces() override {
190 if constexpr (Architecture == Arch::CPU) {
191 long_range_kernel(true, false);
192 }
193#ifdef ESPRESSO_CUDA
194 if constexpr (Architecture == Arch::CUDA) {
196 }
197#endif
198 }
199
201
202 void charge_assign() override;
203 void assign_charge(double q, Utils::Vector3d const &real_pos,
204 bool skip_cache) override;
205 void prepare_fft_mesh(bool reset_weights) override {
206 if (reset_weights) {
208 }
210 using execution_space = Kokkos::DefaultExecutionSpace;
211 auto const num_threads = execution_space().concurrency();
212 Kokkos::realloc(Kokkos::WithoutInitializing, p3m.rs_charge_density_kokkos,
213 num_threads, p3m.local_mesh.size);
214 Kokkos::deep_copy(p3m.rs_charge_density_kokkos, FloatType{0});
215 std::ranges::fill(p3m.rs_charge_density, FloatType{0});
216 }
217
218protected:
219 /** Compute the k-space part of forces and energies. */
220 double long_range_kernel(bool force_flag, bool energy_flag);
221 void calc_influence_function_force() override;
222 void calc_influence_function_energy() override;
223 void scaleby_box_l() override;
224 void init_cpu_kernels();
225#ifdef ESPRESSO_CUDA
226 void init_gpu_kernels();
228 std::shared_ptr<P3MGpuParams> m_gpu_data = nullptr;
229 void request_gpu() const;
230#endif
231private:
232 void kernel_ks_charge_density();
233 void kernel_rs_electric_field();
234};
235
236#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.