ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
influence_function.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019-2024 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include "p3m/common.hpp"
23#include "p3m/for_each_3d.hpp"
24#include "p3m/math.hpp"
25
26#include <utils/Vector.hpp>
27#include <utils/index.hpp>
29#include <utils/math/sqr.hpp>
30
31#include <cmath>
32#include <cstddef>
33#include <functional>
34#include <numbers>
35#include <utility>
36#include <vector>
37
38/**
39 * @brief Hockney/Eastwood/Ballenegger optimal influence function.
40 *
41 * This implements Eq. 30 of @cite cerda08d, which can be used
42 * for monopole and dipole P3M by choosing the appropriate S factor.
43 *
44 * @tparam S Order of the differential operator, e.g. 0 for potential,
45 * 1 for electric field, ...
46 * @tparam m Number of aliasing terms to take into account.
47 *
48 * @param cao Charge assignment order.
49 * @param alpha Ewald splitting parameter.
50 * @param k k-vector to evaluate the function for.
51 * @param h Grid spacing.
52 */
53template <std::size_t S, std::size_t m>
54double G_opt(int cao, double alpha, Utils::Vector3d const &k,
55 Utils::Vector3d const &h) {
56
57 auto const k2 = k.norm2();
58 if (k2 == 0.) {
59 return 0.;
60 }
61
62 auto constexpr limit = 30.;
63 auto constexpr m_start = Utils::Vector3i::broadcast(-m);
64 auto constexpr m_stop = Utils::Vector3i::broadcast(m + 1);
65 auto const exponent_prefactor = Utils::sqr(1. / (2. * alpha));
66 auto const wavevector = (2. * std::numbers::pi) / h;
67 auto const wavevector_i = 1. / wavevector;
68 auto indices = Utils::Vector3i{};
69 auto km = Utils::Vector3d{};
70 auto fnm = Utils::Vector3d{};
71 auto numerator = 0.;
72 auto denominator = 0.;
73
75 m_start, m_stop, indices,
76 [&]() {
77 auto const U2 = std::pow(Utils::product(fnm), 2 * cao);
78 auto const km2 = km.norm2();
79 auto const exponent = exponent_prefactor * km2;
80 if (exponent < limit) {
81 auto const f3 = std::exp(-exponent) * (4. * std::numbers::pi / km2);
82 numerator += U2 * f3 * Utils::int_pow<S>(k * km);
83 }
84 denominator += U2;
85 },
86 [&](unsigned dim, int n) {
87 km[dim] = k[dim] + n * wavevector[dim];
88 fnm[dim] = math::sinc(km[dim] * wavevector_i[dim]);
89 });
90
91 return numerator / (Utils::int_pow<S>(k2) * Utils::sqr(denominator));
92}
93
94/**
95 * @brief Map influence function over a grid.
96 *
97 * This evaluates the optimal influence function @ref G_opt
98 * over a regular grid of k vectors, and returns the values as a vector.
99 *
100 * @tparam S Order of the differential operator, e.g. 0 for potential,
101 * 1 for electric field...
102 * @tparam m Number of aliasing terms to take into account.
103 *
104 * @param params P3M parameters.
105 * @param n_start Lower left corner of the grid.
106 * @param n_stop Upper right corner of the grid.
107 * @param KX k-space x-axis index.
108 * @param KY k-space y-axis index.
109 * @param KZ k-space z-axis index.
110 * @param inv_box_l Inverse box length.
111 * @return Values of G_opt at regular grid points.
112 */
113template <typename FloatType, std::size_t S, std::size_t m = 0>
114std::vector<FloatType> grid_influence_function(
115 P3MParameters const &params, Utils::Vector3i const &n_start,
116 Utils::Vector3i const &n_stop, int const KX, int const KY, int const KZ,
117 Utils::Vector3d const &inv_box_l) {
118
119 auto const shifts = detail::calc_meshift(params.mesh);
120 auto const size = n_stop - n_start;
121
122 /* The influence function grid */
123 auto g = std::vector<FloatType>(Utils::product(size), FloatType(0));
124
125 /* Skip influence function calculation in tuning mode,
126 the results need not be correct for timing. */
127 if (params.tuning) {
128 return g;
129 }
130
131 auto const wavevector = (2. * std::numbers::pi) * inv_box_l;
132 auto const half_mesh = params.mesh / 2;
133 auto indices = Utils::Vector3i{};
134 auto index = std::size_t(0u);
135
136 for_each_3d(n_start, n_stop, indices, [&]() {
137 if ((indices[KX] % half_mesh[0u] != 0) or
138 (indices[KY] % half_mesh[1u] != 0) or
139 (indices[KZ] % half_mesh[2u] != 0)) {
140 auto const k =
141 Utils::Vector3d{{shifts[0u][indices[KX]] * wavevector[0u],
142 shifts[1u][indices[KY]] * wavevector[1u],
143 shifts[2u][indices[KZ]] * wavevector[2u]}};
144 g[index] = FloatType(G_opt<S, m>(params.cao, params.alpha, k, params.a));
145 }
146 ++index;
147 });
148
149 return g;
150}
Vector implementation and trait types for boost qvm interoperability.
T norm2() const
Definition Vector.hpp:137
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
and std::invocable< Projector, unsigned, int > void for_each_3d(detail::IndexVectorConcept auto &&start, detail::IndexVectorConcept auto &&stop, detail::IndexVectorConcept auto &&counters, Kernel &&kernel, Projector &&projector=detail::noop_projector)
Repeat an operation on every element of a 3D grid.
double G_opt(int cao, double alpha, Utils::Vector3d const &k, Utils::Vector3d const &h)
Hockney/Eastwood/Ballenegger optimal influence function.
std::vector< FloatType > grid_influence_function(P3MParameters const &params, Utils::Vector3i const &n_start, Utils::Vector3i const &n_stop, int const KX, int const KY, int const KZ, Utils::Vector3d const &inv_box_l)
Map influence function over a grid.
T product(Vector< T, N > const &v)
Definition Vector.hpp:374
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:28
DEVICE_QUALIFIER auto sinc(T x)
Calculate the function .
Definition math.hpp:53
Common functions for dipolar and charge P3M.
static SteepestDescentParameters params
Currently active steepest descent instance.
Structure to hold P3M parameters and some dependent variables.