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-2022 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#ifndef ESPRESSO_P3M_INFLUENCE_FUNCTION_HPP
20#define ESPRESSO_P3M_INFLUENCE_FUNCTION_HPP
21
22#include "p3m/common.hpp"
23
24#include <utils/Vector.hpp>
25#include <utils/constants.hpp>
26#include <utils/index.hpp>
28#include <utils/math/sinc.hpp>
29#include <utils/math/sqr.hpp>
30
31#include <boost/range/numeric.hpp>
32
33#include <cmath>
34#include <cstddef>
35#include <functional>
36#include <utility>
37#include <vector>
38
39/**
40 * @brief Hockney/Eastwood/Ballenegger optimal influence function.
41 *
42 * This implements Eq. 30 of @cite cerda08d, which can be used
43 * for monopole and dipole P3M by choosing the appropriate S factor.
44 *
45 * @tparam S Order of the differential operator, e.g. 0 for potential,
46 * 1 for electric field, ...
47 * @tparam m Number of aliasing terms to take into account.
48 *
49 * @param cao Charge assignment order.
50 * @param alpha Ewald splitting parameter.
51 * @param k k Vector to evaluate the function for.
52 * @param h Grid spacing.
53 */
54template <std::size_t S, std::size_t m>
55double G_opt(int cao, double alpha, Utils::Vector3d const &k,
56 Utils::Vector3d const &h) {
57 using namespace detail::FFT_indexing;
58 using Utils::int_pow;
59 using Utils::sinc;
60
61 auto constexpr two_pi = 2. * Utils::pi();
62 auto constexpr two_pi_i = 1. / two_pi;
63 auto constexpr limit = 30.;
64
65 auto const k2 = k.norm2();
66 if (k2 == 0.0) {
67 return 0.0;
68 }
69
70 double numerator = 0.0;
71 double denominator = 0.0;
72
73 for (int mx = -m; mx <= m; mx++) {
74 for (int my = -m; my <= m; my++) {
75 for (int mz = -m; mz <= m; mz++) {
76 auto const km =
77 k + two_pi * Utils::Vector3d{mx / h[RX], my / h[RY], mz / h[RZ]};
78 auto const U2 = std::pow(sinc(km[RX] * h[RX] * two_pi_i) *
79 sinc(km[RY] * h[RY] * two_pi_i) *
80 sinc(km[RZ] * h[RZ] * two_pi_i),
81 2 * cao);
82
83 auto const km2 = km.norm2();
84 auto const exponent = Utils::sqr(1. / (2. * alpha)) * km2;
85 if (exponent < limit) {
86 auto const f3 = std::exp(-exponent) * (4. * Utils::pi() / km2);
87 numerator += U2 * f3 * int_pow<S>(k * km);
88 }
89 denominator += U2;
90 }
91 }
92 }
93
94 return numerator / (int_pow<S>(k2) * Utils::sqr(denominator));
95}
96
97/**
98 * @brief Map influence function over a grid.
99 *
100 * This evaluates the optimal influence function @ref G_opt
101 * over a regular grid of k vectors, and returns the values as a vector.
102 *
103 * @tparam S Order of the differential operator, e.g. 0 for potential,
104 * 1 for electric field...
105 * @tparam m Number of aliasing terms to take into account.
106 *
107 * @param params P3M parameters
108 * @param n_start Lower left corner of the grid
109 * @param n_end Upper right corner of the grid.
110 * @param box_l Box size
111 * @return Values of G_opt at regular grid points.
112 */
113template <std::size_t S, std::size_t m = 0>
115 const Utils::Vector3i &n_start,
116 const Utils::Vector3i &n_end,
117 const Utils::Vector3d &box_l) {
118 using namespace detail::FFT_indexing;
119
120 auto const shifts = detail::calc_meshift(params.mesh);
121
122 auto const size = n_end - n_start;
123
124 /* The influence function grid */
125 auto g =
126 std::vector<double>(boost::accumulate(size, 1, std::multiplies<>()), 0.);
127
128 /* Skip influence function calculation in tuning mode,
129 the results need not be correct for timing. */
130 if (params.tuning) {
131 return g;
132 }
133
134 auto const h = Utils::Vector3d{params.a};
135
136 Utils::Vector3i n{};
137 for (n[0] = n_start[0]; n[0] < n_end[0]; n[0]++) {
138 for (n[1] = n_start[1]; n[1] < n_end[1]; n[1]++) {
139 for (n[2] = n_start[2]; n[2] < n_end[2]; n[2]++) {
140 auto const ind = Utils::get_linear_index(n - n_start, size,
142 if ((n[KX] % (params.mesh[RX] / 2) == 0) &&
143 (n[KY] % (params.mesh[RY] / 2) == 0) &&
144 (n[KZ] % (params.mesh[RZ] / 2) == 0)) {
145 g[ind] = 0.0;
146 } else {
147 auto const k = 2 * Utils::pi() *
148 Utils::Vector3d{shifts[RX][n[KX]] / box_l[RX],
149 shifts[RY][n[KY]] / box_l[RY],
150 shifts[RZ][n[KZ]] / box_l[RZ]};
151
152 g[ind] = G_opt<S, m>(params.cao, params.alpha, k, h);
153 }
154 }
155 }
156 }
157
158 return g;
159}
160
161#endif
Vector implementation and trait types for boost qvm interoperability.
float h[3]
T norm2() const
Definition Vector.hpp:130
Common functions for dipolar and charge P3M.
double G_opt(int cao, double alpha, Utils::Vector3d const &k, Utils::Vector3d const &h)
Hockney/Eastwood/Ballenegger optimal influence function.
std::vector< double > grid_influence_function(const P3MParameters &params, const Utils::Vector3i &n_start, const Utils::Vector3i &n_end, const Utils::Vector3d &box_l)
Map influence function over a grid.
DEVICE_QUALIFIER constexpr T pi()
Ratio of diameter and circumference of a circle.
Definition constants.hpp:36
int get_linear_index(int a, int b, int c, const Vector3i &adim, MemoryOrder memory_order=MemoryOrder::COLUMN_MAJOR)
get the linear index from the position (a,b,c) in a 3D grid of dimensions adim.
Definition index.hpp:43
DEVICE_QUALIFIER T sinc(T d)
Calculates the sinc-function as sin(PI*x)/(PI*x).
Definition sinc.hpp:45
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
Definition sqr.hpp:26
DEVICE_QUALIFIER constexpr T int_pow(T x)
Calculate integer powers.
Definition int_pow.hpp:61
static SteepestDescentParameters params
Currently active steepest descent instance.
Structure to hold P3M parameters and some dependent variables.
Definition common.hpp:67