24#if defined(ESPRESSO_P3M)
90template <std::
size_t S, std::
size_t m>
93 auto const k2 = k.
norm2();
98 auto constexpr exp_limit = 30.;
101 auto const cao = params.
cao;
103 auto const wavevector = (2. * std::numbers::pi) / params.
a;
104 auto const wavevector_i = 1. / wavevector;
109 auto denominator = 0.;
112 m_start, m_stop, indices,
115 auto const km2 = km.norm2();
116 auto const exp_term = exponent_prefactor * km2;
117 if (exp_term < exp_limit) {
118 auto const f3 = std::exp(-exp_term) * (4. * std::numbers::pi / km2);
119 numerator += U2 * f3 * Utils::int_pow<S>(k * km);
123 [&](
unsigned dim,
int n) {
124 km[dim] = k[dim] + n * wavevector[dim];
125 fnm[dim] =
math::sinc(km[dim] * wavevector_i[dim]);
128 if (numerator == 0. and denominator != 0.) {
132 return numerator / (Utils::int_pow<S>(k2) *
Utils::sqr(denominator));
150template <
typename FloatType, std::size_t S, std::size_t m,
157 auto const size = n_stop - n_start;
160 auto g = std::vector<FloatType>(
Utils::product(size), FloatType(0));
168 auto const wavevector = (2. * std::numbers::pi) * inv_box_l;
169 auto const half_mesh = params.
mesh / 2;
173 if ((indices[0u] % half_mesh[0u] != 0) or
174 (indices[1u] % half_mesh[1u] != 0) or
175 (indices[2u] % half_mesh[2u] != 0)) {
178 shifts[1u][indices[1u]] * wavevector[1u],
179 shifts[2u][indices[2u]] * wavevector[2u]}};
181 Utils::get_linear_index<memory_order>(indices - n_start, size);
182 g[index] = FloatType(G_opt<S, m>(params, k));
Vector implementation and trait types for boost qvm interoperability.
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
constexpr T norm2() const
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.
std::vector< FloatType > grid_influence_function(P3MParameters const ¶ms, Utils::Vector3i const &n_start, Utils::Vector3i const &n_stop, Utils::Vector3d const &inv_box_l)
Map influence function over a grid.
double G_opt(P3MParameters const ¶ms, Utils::Vector3d const &k)
Calculate the aliasing sums for the optimal influence function.
T product(Vector< T, N > const &v)
DEVICE_QUALIFIER constexpr T sqr(T x)
Calculates the SQuaRe of x.
DEVICE_QUALIFIER auto sinc(T x)
Calculate the function .
Common functions for dipolar and charge P3M.
std::array< std::vector< int >, 3 > calc_p3m_mesh_shift(Utils::Vector3i const &mesh_size, bool zero_out_midpoint=false)
Calculate indices that shift P3MParameters::mesh by mesh/2.
Structure to hold P3M parameters and some dependent variables.
double alpha
unscaled alpha_L for use with fast inline functions only
int cao
charge assignment order ([0,7]).
bool tuning
tuning or production?
Utils::Vector3i mesh
number of mesh points per coordinate direction (>0), in real space.
Utils::Vector3d a
mesh constant.