ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
dp3m.impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2024 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 DP3M
27
29
30#include "p3m/common.hpp"
31#include "p3m/data_struct.hpp"
32#include "p3m/interpolation.hpp"
33
34#include "ParticleRange.hpp"
35
36#include <utils/Vector.hpp>
37
38#include <memory>
39#include <stdexcept>
40#include <type_traits>
41#include <utility>
42#include <vector>
43
44template <typename FloatType>
45struct p3m_data_struct_dipoles : public p3m_data_struct<FloatType> {
46 using p3m_data_struct<FloatType>::p3m_data_struct;
47
48 /** number of dipolar particles (only on head node). */
49 int sum_dip_part = 0;
50 /** Sum of square of magnetic dipoles (only on head node). */
51 double sum_mu2 = 0.;
52
53 /** position shift for calculation of first assignment mesh point. */
54 double pos_shift = 0.;
55
56 /** cached k-space self-energy correction */
57 double energy_correction = 0.;
58 /** k-space scalar mesh for k-space calculations. */
59 std::vector<FloatType> ks_scalar;
60
62};
63
64template <typename FloatType, Arch Architecture>
65struct DipolarP3MImpl : public DipolarP3M {
66 ~DipolarP3MImpl() override = default;
67
68 /** @brief Dipolar P3M parameters. */
70
71private:
72 /** @brief Coulomb P3M meshes and FFT algorithm. */
73 std::unique_ptr<p3m_data_struct_dipoles<FloatType>> dp3m_impl;
74 int tune_timings;
75 bool tune_verbose;
76 bool m_is_tuned;
77
78public:
80 std::unique_ptr<p3m_data_struct_dipoles<FloatType>> &&dp3m_handle,
81 double prefactor, int tune_timings, bool tune_verbose)
82 : DipolarP3M(dp3m_handle->params), dp3m{*dp3m_handle},
83 dp3m_impl{std::move(dp3m_handle)}, tune_timings{tune_timings},
84 tune_verbose{tune_verbose} {
85
86 if (tune_timings <= 0) {
87 throw std::domain_error("Parameter 'timings' must be > 0");
88 }
89 if (dp3m.params.mesh != Utils::Vector3i::broadcast(dp3m.params.mesh[0])) {
90 throw std::domain_error("DipolarP3M requires a cubic mesh");
91 }
92 m_is_tuned = not dp3m.params.tuning;
93 dp3m.params.tuning = false;
95 }
96
97 void init() override {
98 if constexpr (Architecture == Arch::CPU) {
100 }
101 }
102 void tune() override;
103 void count_magnetic_particles() override;
104
105 [[nodiscard]] bool is_tuned() const noexcept override { return m_is_tuned; }
106 [[nodiscard]] bool is_gpu() const noexcept override {
107 return Architecture == Arch::GPU;
108 }
109 [[nodiscard]] bool is_double_precision() const noexcept override {
110 return std::is_same_v<FloatType, double>;
111 }
112
113 void on_activation() override {
115 tune();
116 }
117
118 double long_range_energy(ParticleRange const &particles) override {
119 return long_range_kernel(false, true, particles);
120 }
121
122 void add_long_range_forces(ParticleRange const &particles) override {
123 if constexpr (Architecture == Arch::CPU) {
124 long_range_kernel(true, false, particles);
125 }
126 }
127
128 void dipole_assign(ParticleRange const &particles) override;
129
130protected:
131 /** Compute the k-space part of forces and energies. */
132 double long_range_kernel(bool force_flag, bool energy_flag,
133 ParticleRange const &particles);
134 double calc_average_self_energy_k_space() const override;
135 void calc_energy_correction() override;
136 void calc_influence_function_force() override;
137 void calc_influence_function_energy() override;
138 double calc_surface_term(bool force_flag, bool energy_flag,
139 ParticleRange const &particles) override;
140 void init_cpu_kernels();
141 void scaleby_box_l() override;
142};
143
144template <typename FloatType, Arch Architecture,
145 template <typename> class FFTBackendImpl,
146 template <typename> class P3MFFTMeshImpl, class... Args>
147std::shared_ptr<DipolarP3M> new_dp3m_handle(P3MParameters &&p3m,
148 Args &&...args) {
149 auto obj = std::make_shared<DipolarP3MImpl<FloatType, Architecture>>(
150 std::make_unique<p3m_data_struct_dipoles<FloatType>>(std::move(p3m)),
151 std::forward<Args>(args)...);
152 obj->dp3m.template make_mesh_instance<P3MFFTMeshImpl<FloatType>>();
153 obj->dp3m.template make_fft_instance<FFTBackendImpl<FloatType>>();
154 return obj;
155}
156
157#endif // DP3M
Vector implementation and trait types for boost qvm interoperability.
void set_prefactor(double new_prefactor)
double prefactor
Magnetostatics prefactor.
A range of particles.
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value)
Create a vector that has all entries set to the same value.
Definition Vector.hpp:110
Cache for interpolation weights.
This file contains the defaults for ESPResSo.
P3M algorithm for long-range magnetic dipole-dipole interaction.
std::shared_ptr< DipolarP3M > new_dp3m_handle(P3MParameters &&p3m, Args &&...args)
Common functions for dipolar and charge P3M.
Arch
static SteepestDescentParameters params
Currently active steepest descent instance.
void calc_energy_correction() override
Definition dp3m.cpp:893
double long_range_kernel(bool force_flag, bool energy_flag, ParticleRange const &particles)
Compute the k-space part of forces and energies.
Definition dp3m.cpp:247
double long_range_energy(ParticleRange const &particles) override
p3m_data_struct_dipoles< FloatType > & dp3m
Dipolar P3M parameters.
Definition dp3m.impl.hpp:69
double calc_surface_term(bool force_flag, bool energy_flag, ParticleRange const &particles) override
Definition dp3m.cpp:452
void dipole_assign(ParticleRange const &particles) override
Definition dp3m.cpp:177
bool is_double_precision() const noexcept override
void init_cpu_kernels()
Definition dp3m.cpp:128
void calc_influence_function_energy() override
Definition dp3m.cpp:527
bool is_gpu() const noexcept override
void add_long_range_forces(ParticleRange const &particles) override
void count_magnetic_particles() override
Definition dp3m.cpp:84
~DipolarP3MImpl() override=default
DipolarP3MImpl(std::unique_ptr< p3m_data_struct_dipoles< FloatType > > &&dp3m_handle, double prefactor, int tune_timings, bool tune_verbose)
Definition dp3m.impl.hpp:79
void calc_influence_function_force() override
Definition dp3m.cpp:520
bool is_tuned() const noexcept override
void init() override
Definition dp3m.impl.hpp:97
void on_activation() override
void tune() override
Definition dp3m.cpp:648
void scaleby_box_l() override
Definition dp3m.cpp:880
double calc_average_self_energy_k_space() const override
Definition dp3m.cpp:115
Dipolar P3M solver.
Definition dp3m.hpp:59
void sanity_checks() const
Definition dp3m.hpp:83
Structure to hold P3M parameters and some dependent variables.
double energy_correction
cached k-space self-energy correction
Definition dp3m.impl.hpp:57
int sum_dip_part
number of dipolar particles (only on head node).
Definition dp3m.impl.hpp:49
double pos_shift
position shift for calculation of first assignment mesh point.
Definition dp3m.impl.hpp:54
p3m_interpolation_cache inter_weights
Definition dp3m.impl.hpp:61
double sum_mu2
Sum of square of magnetic dipoles (only on head node).
Definition dp3m.impl.hpp:51
std::vector< FloatType > ks_scalar
k-space scalar mesh for k-space calculations.
Definition dp3m.impl.hpp:59
Base class for the electrostatics and magnetostatics P3M algorithms.