ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 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/** \file
23 * Common functions for dipolar and charge P3M.
24 *
25 * We use here a P3M (Particle-Particle Particle-Mesh) method based
26 * on the Ewald summation. Details of the used method can be found in
27 * @cite hockney88a and @cite deserno98a @cite deserno98b. The file p3m
28 * contains only the Particle-Mesh part.
29 *
30 * Further reading: @cite ewald21a, @cite hockney88a, @cite deserno98a,
31 * @cite deserno98b, @cite deserno00e, @cite deserno00b, @cite cerda08d
32 *
33 */
34
35#pragma once
36
37#include "config/config.hpp"
38
39#include <utils/Vector.hpp>
40
41#include <array>
42#include <vector>
43
44/** This value indicates metallic boundary conditions. */
45auto constexpr P3M_EPSILON_METALLIC = 0.0;
46
47#if defined(P3M) || defined(DP3M)
48
49#include "LocalBox.hpp"
50
51#include <array>
52#include <stdexcept>
53#include <vector>
54
55namespace detail {
56/** @brief Index helpers for direct and reciprocal space.
57 * After the FFT the data is in order YZX, which
58 * means that Y is the slowest changing index.
59 */
60namespace FFT_indexing {
61enum FFT_REAL_VECTOR : int { RX = 0, RY = 1, RZ = 2 };
62enum FFT_WAVE_VECTOR : int { KY = 0, KZ = 1, KX = 2 };
63} // namespace FFT_indexing
64} // namespace detail
65
66/** Structure to hold P3M parameters and some dependent variables. */
68 /** tuning or production? */
69 bool tuning;
70 /** Ewald splitting parameter (0<alpha<1), rescaled to
71 * @p alpha_L = @p alpha * @p box_l. */
72 double alpha_L;
73 /** cutoff radius for real space electrostatics (>0), rescaled to
74 * @p r_cut_iL = @p r_cut * @p box_l_i. */
75 double r_cut_iL;
76 /** number of mesh points per coordinate direction (>0). */
78 /** offset of the first mesh point (lower left corner) from the
79 * coordinate origin ([0,1[). */
81 /** charge assignment order ([0,7]). */
82 int cao;
83 /** accuracy of the actual parameter set. */
84 double accuracy;
85
86 /** epsilon of the "surrounding dielectric". */
87 double epsilon;
88 /** cutoff for charge assignment. */
90 /** mesh constant. */
92 /** inverse mesh constant. */
94 /** unscaled @ref P3MParameters::alpha_L "alpha_L" for use with fast
95 * inline functions only */
96 double alpha;
97 /** unscaled @ref P3MParameters::r_cut_iL "r_cut_iL" for use with fast
98 * inline functions only */
99 double r_cut;
100 /** number of points unto which a single charge is interpolated, i.e.
101 * @ref P3MParameters::cao "cao" cubed */
102 int cao3;
103
104 P3MParameters(bool tuning, double epsilon, double r_cut,
106 int cao, double alpha, double accuracy)
107 : tuning{tuning}, alpha_L{0.}, r_cut_iL{0.}, mesh{mesh},
109 cao_cut{}, a{}, ai{}, alpha{alpha}, r_cut{r_cut}, cao3{-1} {
110
111 auto constexpr value_to_tune = -1.;
112
113 if (epsilon < 0.) {
114 throw std::domain_error("Parameter 'epsilon' must be >= 0");
115 }
116
117 if (accuracy <= 0.) {
118 throw std::domain_error("Parameter 'accuracy' must be > 0");
119 }
120
121 if (r_cut <= 0.) {
122 if (tuning and r_cut == value_to_tune) {
123 this->r_cut = 0.;
124 } else {
125 throw std::domain_error("Parameter 'r_cut' must be > 0");
126 }
127 }
128
129 if (alpha <= 0.) {
130 if (tuning and alpha == value_to_tune) {
131 this->alpha = 0.;
132 } else {
133 throw std::domain_error("Parameter 'alpha' must be > 0");
134 }
135 }
136
137 if (not(mesh >= Utils::Vector3i::broadcast(1) or
138 ((mesh[0] >= 1) and (mesh == Utils::Vector3i{{mesh[0], -1, -1}})) or
139 (tuning and mesh == Utils::Vector3i::broadcast(-1)))) {
140 throw std::domain_error("Parameter 'mesh' must be > 0");
141 }
142
143 if (not(mesh_off >= Utils::Vector3d::broadcast(0.) and
146 this->mesh_off = Utils::Vector3d::broadcast(P3M_MESHOFF);
147 } else {
148 throw std::domain_error("Parameter 'mesh_off' must be >= 0 and <= 1");
149 }
150 }
151
152 if ((cao < 1 or cao > 7) and (not tuning or cao != -1)) {
153 throw std::domain_error("Parameter 'cao' must be >= 1 and <= 7");
154 }
155
156 if (not tuning and (Utils::Vector3i::broadcast(cao) > mesh)) {
157 throw std::domain_error("Parameter 'cao' cannot be larger than 'mesh'");
158 }
159 }
160
161 /**
162 * @brief Recalculate quantities derived from the mesh and box length:
163 * @ref P3MParameters::a "a",
164 * @ref P3MParameters::ai "ai" and
165 * @ref P3MParameters::cao_cut "cao_cut".
166 */
170 cao_cut = (static_cast<double>(cao) / 2.) * a;
171 }
172
173 /**
174 * @brief Convert spatial position to grid position.
175 * To get the grid index, round the result to the nearest integer.
176 */
177 auto calc_grid_pos(Utils::Vector3d const &pos) const {
179 }
180};
181
182/** Structure for local mesh parameters. */
184 /* local mesh characterization. */
185 /** dimension (size) of local mesh. */
187 /** number of local mesh points. */
188 int size;
189 /** index of lower left corner of the
190 local mesh in the global mesh. */
191 int ld_ind[3];
192 /** position of the first local mesh point. */
193 double ld_pos[3];
194 /** dimension of mesh inside node domain. */
195 int inner[3];
196 /** inner left down grid point */
197 int in_ld[3];
198 /** inner up right grid point + (1,1,1) */
199 int in_ur[3];
200 /** number of margin mesh points. */
201 int margin[6];
202 /** number of margin mesh points from neighbour nodes */
203 int r_margin[6];
204 /** offset between mesh lines of the last dimension */
206 /** offset between mesh lines of the two last dimensions */
208
209 /**
210 * @brief Recalculate quantities derived from the mesh and box length:
211 * @ref P3MLocalMesh::ld_pos "ld_pos" (position of the left down mesh).
212 */
214 // spatial position of left down mesh point
215 for (unsigned int i = 0; i < 3; i++) {
216 ld_pos[i] = (ld_ind[i] + params.mesh_off[i]) * params.a[i];
217 }
218 }
219
220 /**
221 * @brief Calculate properties of the local FFT mesh
222 * for the charge assignment process.
223 */
225 LocalBox const &local_geo, double skin,
226 double space_layer);
227};
228
229/** One of the aliasing sums used to compute k-space errors.
230 * Fortunately the one which is most important (because it converges
231 * most slowly, since it is not damped exponentially) can be
232 * calculated analytically. The result (which depends on the order of
233 * the spline interpolation) can be written as an even trigonometric
234 * polynomial. The results are tabulated here (the employed formula
235 * is eq. (7.66) in @cite hockney88a).
236 */
237double p3m_analytic_cotangent_sum(int n, double mesh_i, int cao);
238
239#endif /* P3M || DP3M */
240
241namespace detail {
242/** Calculate indices that shift @ref P3MParameters::mesh "mesh" by `mesh/2`.
243 * For each mesh size @f$ n @f$ in @c mesh_size, create a sequence of integer
244 * values @f$ \left( 0, \ldots, \lfloor n/2 \rfloor, -\lfloor n/2 \rfloor,
245 * \ldots, -1\right) @f$ if @c zero_out_midpoint is false, otherwise
246 * @f$ \left( 0, \ldots, \lfloor n/2 - 1 \rfloor, 0, -\lfloor n/2 \rfloor,
247 * \ldots, -1\right) @f$.
248 */
249std::array<std::vector<int>, 3> inline calc_meshift(
250 Utils::Vector3i const &mesh_size, bool zero_out_midpoint = false) {
251 std::array<std::vector<int>, 3> ret{};
252
253 for (unsigned int i = 0; i < 3; i++) {
254 ret[i] = std::vector<int>(mesh_size[i]);
255
256 for (int j = 1; j <= mesh_size[i] / 2; j++) {
257 ret[i][j] = j;
258 ret[i][mesh_size[i] - j] = -j;
259 }
260 if (zero_out_midpoint)
261 ret[i][mesh_size[i] / 2] = 0;
262 }
263
264 return ret;
265}
266} // namespace detail
Vector implementation and trait types for boost qvm interoperability.
__shared__ int pos[MAXDEPTH *THREADS5/WARPSIZE]
static Vector< T, N > broadcast(T const &s)
Create a vector that has all entries set to one value.
Definition Vector.hpp:110
double p3m_analytic_cotangent_sum(int n, double mesh_i, int cao)
One of the aliasing sums used to compute k-space errors.
Definition common.cpp:37
auto constexpr P3M_EPSILON_METALLIC
This value indicates metallic boundary conditions.
Definition common.hpp:45
This file contains the defaults for ESPResSo.
#define P3M_MESHOFF
P3M: Default for offset of first mesh point from the origin (left down corner of the simulation box).
Definition config.hpp:46
auto hadamard_division(Vector< T, N > const &a, Vector< U, N > const &b)
Definition Vector.hpp:407
auto hadamard_product(Vector< T, N > const &a, Vector< U, N > const &b)
Definition Vector.hpp:364
static SteepestDescentParameters params
Currently active steepest descent instance.
Structure for local mesh parameters.
Definition common.hpp:183
Utils::Vector3i dim
dimension (size) of local mesh.
Definition common.hpp:186
int in_ur[3]
inner up right grid point + (1,1,1)
Definition common.hpp:199
int size
number of local mesh points.
Definition common.hpp:188
void recalc_ld_pos(P3MParameters const &params)
Recalculate quantities derived from the mesh and box length: ld_pos (position of the left down mesh).
Definition common.hpp:213
void calc_local_ca_mesh(P3MParameters const &params, LocalBox const &local_geo, double skin, double space_layer)
Calculate properties of the local FFT mesh for the charge assignment process.
Definition common.cpp:78
int in_ld[3]
inner left down grid point
Definition common.hpp:197
int r_margin[6]
number of margin mesh points from neighbour nodes
Definition common.hpp:203
int margin[6]
number of margin mesh points.
Definition common.hpp:201
int q_2_off
offset between mesh lines of the last dimension
Definition common.hpp:205
double ld_pos[3]
position of the first local mesh point.
Definition common.hpp:193
int inner[3]
dimension of mesh inside node domain.
Definition common.hpp:195
int ld_ind[3]
index of lower left corner of the local mesh in the global mesh.
Definition common.hpp:191
int q_21_off
offset between mesh lines of the two last dimensions
Definition common.hpp:207
Structure to hold P3M parameters and some dependent variables.
Definition common.hpp:67
auto calc_grid_pos(Utils::Vector3d const &pos) const
Convert spatial position to grid position.
Definition common.hpp:177
Utils::Vector3d cao_cut
cutoff for charge assignment.
Definition common.hpp:89
double alpha
unscaled alpha_L for use with fast inline functions only
Definition common.hpp:96
P3MParameters(bool tuning, double epsilon, double r_cut, Utils::Vector3i const &mesh, Utils::Vector3d const &mesh_off, int cao, double alpha, double accuracy)
Definition common.hpp:104
double r_cut_iL
cutoff radius for real space electrostatics (>0), rescaled to r_cut_iL = r_cut * box_l_i.
Definition common.hpp:75
int cao
charge assignment order ([0,7]).
Definition common.hpp:82
double accuracy
accuracy of the actual parameter set.
Definition common.hpp:84
double alpha_L
Ewald splitting parameter (0.
Definition common.hpp:72
int cao3
number of points unto which a single charge is interpolated, i.e.
Definition common.hpp:102
Utils::Vector3d mesh_off
offset of the first mesh point (lower left corner) from the coordinate origin ([0,...
Definition common.hpp:80
Utils::Vector3d ai
inverse mesh constant.
Definition common.hpp:93
double r_cut
unscaled r_cut_iL for use with fast inline functions only
Definition common.hpp:99
void recalc_a_ai_cao_cut(Utils::Vector3d const &box_l)
Recalculate quantities derived from the mesh and box length: a, ai and cao_cut.
Definition common.hpp:167
bool tuning
tuning or production?
Definition common.hpp:69
Utils::Vector3i mesh
number of mesh points per coordinate direction (>0).
Definition common.hpp:77
double epsilon
epsilon of the "surrounding dielectric".
Definition common.hpp:87
Utils::Vector3d a
mesh constant.
Definition common.hpp:91