21#ifndef ESPRESSO_CORE_P3M_INFLUENCE_FUNCTION_DIPOLAR_HPP
22#define ESPRESSO_CORE_P3M_INFLUENCE_FUNCTION_DIPOLAR_HPP
37#include <boost/range/numeric.hpp>
56template <std::
size_t S>
62 auto constexpr exp_limit = 30.;
63 auto const exponent = 2. *
params.cao;
66 auto denominator = 0.0;
68 auto const f1 = 1.0 /
static_cast<double>(
params.mesh[0]);
71 for (
int mx = -limit; mx <= limit; mx++) {
72 auto const nmx = shift[0] +
params.mesh[0] * mx;
73 auto const sx = std::pow(sinc(f1 * nmx), exponent);
74 for (
int my = -limit; my <= limit; my++) {
75 auto const nmy = shift[1] +
params.mesh[0] * my;
76 auto const sy = sx * std::pow(sinc(f1 * nmy), exponent);
77 for (
int mz = -limit; mz <= limit; mz++) {
78 auto const nmz = shift[2] +
params.mesh[0] * mz;
79 auto const sz = sy * std::pow(sinc(f1 * nmz), exponent);
81 auto const exp_term = f2 * nm2;
82 if (exp_term < exp_limit) {
83 auto const f3 = sz * std::exp(-exp_term) / nm2;
84 auto const n_nm = d_op[0] * nmx + d_op[1] * nmy + d_op[2] * nmz;
85 numerator += f3 * int_pow<S>(n_nm);
91 return numerator / (int_pow<S>(
static_cast<double>(d_op.
norm2())) *
109template <std::
size_t S>
115 auto const size = n_end - n_start;
119 std::vector<double>(boost::accumulate(size, 1, std::multiplies<>()), 0.);
127 double fak1 = Utils::int_pow<3>(
static_cast<double>(
params.mesh[0])) * 2.0 /
130 auto const shifts = detail::calc_meshift(
params.mesh,
false);
131 auto const d_ops = detail::calc_meshift(
params.mesh,
true);
134 for (n[0] = n_start[0]; n[0] < n_end[0]; n[0]++) {
135 for (n[1] = n_start[1]; n[1] < n_end[1]; n[1]++) {
136 for (n[2] = n_start[2]; n[2] < n_end[2]; n[2]++) {
140 if (((n[0] % (
params.mesh[0] / 2) == 0) &&
141 (n[1] % (
params.mesh[0] / 2) == 0) &&
142 (n[2] % (
params.mesh[0] / 2) == 0))) {
149 auto const fak2 = G_opt_dipolar<S>(
params, shift, d_op);
150 g[ind] = fak1 * fak2;
162 auto const exponent = 2. *
params.cao;
166 auto const f1 = 1.0 /
static_cast<double>(
params.mesh[0]);
168 for (
int mx = -limit; mx <= limit; mx++) {
169 auto const nmx = shift[0] +
params.mesh[0] * mx;
170 auto const sx = std::pow(sinc(f1 * nmx), exponent);
171 for (
int my = -limit; my <= limit; my++) {
172 auto const nmy = shift[1] +
params.mesh[0] * my;
173 auto const sy = sx * std::pow(sinc(f1 * nmy), exponent);
174 for (
int mz = -limit; mz <= limit; mz++) {
175 auto const nmz = shift[2] +
params.mesh[0] * mz;
176 auto const sz = sy * std::pow(sinc(f1 * nmz), exponent);
196 auto const size = n_end - n_start;
198 auto const shifts = detail::calc_meshift(
params.mesh,
false);
199 auto const d_ops = detail::calc_meshift(
params.mesh,
true);
203 for (n[0] = n_start[0]; n[0] < n_end[0]; n[0]++) {
204 for (n[1] = n_start[1]; n[1] < n_end[1]; n[1]++) {
205 for (n[2] = n_start[2]; n[2] < n_end[2]; n[2]++) {
206 if (((n[0] % (
params.mesh[0] / 2) == 0) &&
207 (n[1] % (
params.mesh[0] / 2) == 0) &&
208 (n[2] % (
params.mesh[0] / 2) == 0))) {
218 energy += g[ind] * U2 * d_op.norm2();
Vector implementation and trait types for boost qvm interoperability.
Common functions for dipolar and charge P3M.
This file contains the defaults for ESPResSo.
#define P3M_BRILLOUIN
P3M: Number of Brillouin zones taken into account in the calculation of the optimal influence functio...
double G_opt_dipolar(P3MParameters const ¶ms, Utils::Vector3i const &shift, Utils::Vector3i const &d_op)
Calculate the aliasing sums for the optimal influence function.
double grid_influence_function_self_energy(P3MParameters const ¶ms, Utils::Vector3i const &n_start, Utils::Vector3i const &n_end, std::vector< double > const &g)
Calculate self-energy of the influence function.
std::vector< double > grid_influence_function(P3MParameters const ¶ms, Utils::Vector3i const &n_start, Utils::Vector3i const &n_end, Utils::Vector3d const &box_l)
Map influence function over a grid.
double G_opt_dipolar_self_energy(P3MParameters const ¶ms, Utils::Vector3i const &shift)
DEVICE_QUALIFIER constexpr T pi()
Ratio of diameter and circumference of a circle.
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.
DEVICE_QUALIFIER T sinc(T d)
Calculates the sinc-function as sin(PI*x)/(PI*x).
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
DEVICE_QUALIFIER constexpr T int_pow(T x)
Calculate integer powers.
static SteepestDescentParameters params
Currently active steepest descent instance.
Structure to hold P3M parameters and some dependent variables.