QMCPACK
qmcplusplus::ewaldref Namespace Reference

Classes

class  KspaceEwaldTerm
 Functor for term within the k-space sum in Drummond 2008 formula 6. More...
 
class  KspaceMadelungTerm
 Functor for term within the k-space sum in Drummond 2008 formula 7. More...
 
class  RspaceEwaldTerm
 Functor for term within the real-space sum in Drummond 2008 formula 6. More...
 
class  RspaceMadelungTerm
 Functor for term within the real-space sum in Drummond 2008 formula 7. More...
 

Typedefs

using int_t = int
 Type for integers. More...
 
using real_t = double
 Type for floating point numbers. More...
 
using IntVec = TinyVector< int_t, DIM >
 Type for integer vectors of length DIM. More...
 
using RealVec = TinyVector< real_t, DIM >
 Type for floating point vectors of length DIM. More...
 
using RealMat = Tensor< real_t, DIM >
 Type for floating point matrices of shape DIM,DIM. More...
 
using PosArray = std::vector< RealVec >
 Type for lists of particle positions. More...
 
using ChargeArray = std::vector< real_t >
 Type for lists of particle charges. More...
 

Enumerations

enum  { DIM = 3 }
 Reference Ewald implemented for 3D only. More...
 

Functions

template<typename T >
real_t gridSum (T &function, bool zero=true, real_t tol=1e-11)
 Perform a sum over successively larger cubic integer grids in DIM dimensional space for arbitrary functors. More...
 
real_t getKappaMadelung (real_t volume)
 Find the optimal kappa for Madelung sums. More...
 
real_t madelungSum (const RealMat &a, real_t tol=1e-10)
 Compute the Madelung constant to a given tolerance. More...
 
real_t getKappaEwald (real_t volume)
 Find the optimal kappa for Ewald pair sums. More...
 
real_t ewaldSum (const RealVec &r, const RealMat &a, real_t tol=1e-10)
 Compute the Ewald interaction of a particle pair to a given tolerance. More...
 
real_t ewaldEnergy (const RealMat &a, const PosArray &R, const ChargeArray &Q, real_t tol)
 Compute the total Ewald potential energy for a collection of charges. More...
 

Typedef Documentation

◆ ChargeArray

using ChargeArray = std::vector<real_t>

Type for lists of particle charges.

Definition at line 54 of file EwaldRef.h.

◆ int_t

using int_t = int

Type for integers.

Definition at line 42 of file EwaldRef.h.

◆ IntVec

Type for integer vectors of length DIM.

Definition at line 46 of file EwaldRef.h.

◆ PosArray

using PosArray = std::vector<RealVec>

Type for lists of particle positions.

Definition at line 52 of file EwaldRef.h.

◆ real_t

using real_t = double

Type for floating point numbers.

Definition at line 44 of file EwaldRef.h.

◆ RealMat

using RealMat = Tensor<real_t, DIM>

Type for floating point matrices of shape DIM,DIM.

Definition at line 50 of file EwaldRef.h.

◆ RealVec

Type for floating point vectors of length DIM.

Definition at line 48 of file EwaldRef.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Reference Ewald implemented for 3D only.

Enumerator
DIM 

Definition at line 36 of file EwaldRef.h.

37 {
38  DIM = 3
39 };

Function Documentation

◆ ewaldEnergy()

real_t ewaldEnergy ( const RealMat a,
const PosArray R,
const ChargeArray Q,
real_t  tol 
)

Compute the total Ewald potential energy for a collection of charges.

Corresponds to the entirety of Drummond 2008 formula 5, but for arbitrary charges.

Parameters
aReal-space cell axes.
RList of particle coordinates.
RList of particle charges.
tolTolerance for the total potential energy in Ha.

Definition at line 337 of file EwaldRef.cpp.

References qmcplusplus::abs(), qmcplusplus::createGlobalTimer(), DIM, qmcplusplus::dot(), ewaldSum(), qmcplusplus::floor(), qmcplusplus::inverse(), madelungSum(), and qmcplusplus::Units::force::N.

Referenced by CoulombPBCAA::CoulombPBCAA(), and qmcplusplus::TEST_CASE().

338 {
339  // Timer for EwaldRef
340  ScopedTimer totalEwaldTimer(createGlobalTimer("EwaldRef"));
341 
342  // Number of particles
343  const size_t N = R.size();
344 
345  // Total Ewald potential energy
346  real_t ve = 0.0;
347 
348  {
349  // Sum Madelung contributions
350  ScopedTimer totalMadelungTimer(createGlobalTimer("MadelungSum"));
351  // Maximum self-interaction charge product
352  real_t qqmax = 0.0;
353  for (size_t i = 0; i < N; ++i)
354  qqmax = std::max(std::abs(Q[i] * Q[i]), qqmax);
355 
356  // Compute the Madelung term (Drummond 2008 formula 7)
357  real_t vm = madelungSum(a, tol * 2. / qqmax);
358 
359  // Sum the Madelung self interaction for each particle
360  for (size_t i = 0; i < N; ++i)
361  ve += Q[i] * Q[i] * vm / 2;
362  }
363 
364  {
365  // Sum the interaction terms for all particle pairs
366  ScopedTimer EwaldSumTimer(createGlobalTimer("EwaldSum"));
367 
368 #pragma omp parallel for reduction(+ : ve)
369  for (size_t i = 1; i < N / 2 + 1; ++i)
370  {
371  for (size_t j = 0; j < i; ++j)
372  {
373  real_t qq = Q[i] * Q[j];
374  RealVec reduced = dot(R[i] - R[j], inverse(a));
375  for (size_t dim = 0; dim < DIM; dim++)
376  reduced[dim] -= std::floor(reduced[dim]);
377  RealVec rr = dot(reduced, a);
378  ve += qq * ewaldSum(rr, a, tol / qq);
379  }
380 
381  const size_t i_reverse = N - i;
382  if (i == i_reverse)
383  continue;
384 
385  for (size_t j = 0; j < i_reverse; ++j)
386  {
387  real_t qq = Q[i_reverse] * Q[j];
388  RealVec reduced = dot(R[i_reverse] - R[j], inverse(a));
389  for (size_t dim = 0; dim < DIM; dim++)
390  reduced[dim] -= std::floor(reduced[dim]);
391  RealVec rr = dot(reduced, a);
392  ve += qq * ewaldSum(rr, a, tol / qq);
393  }
394  }
395  }
396 
397  return ve;
398 }
T dot(T *a, T *b)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
ScopeGuard< NewTimer > ScopedTimer
Definition: NewTimer.h:257
TinyVector< real_t, DIM > RealVec
Type for floating point vectors of length DIM.
Definition: EwaldRef.h:48
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
real_t ewaldSum(const RealVec &r, const RealMat &a, real_t tol=1e-10)
Compute the Ewald interaction of a particle pair to a given tolerance.
Definition: EwaldRef.cpp:292
Tensor< T, D > inverse(const Tensor< T, D > &a)
Definition: TensorOps.h:879
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44
real_t madelungSum(const RealMat &a, real_t tol=1e-10)
Compute the Madelung constant to a given tolerance.
Definition: EwaldRef.cpp:232
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)

◆ ewaldSum()

real_t qmcplusplus::ewaldref::ewaldSum ( const RealVec r,
const RealMat a,
real_t  tol = 1e-10 
)

Compute the Ewald interaction of a particle pair to a given tolerance.

Corresponds to the entirety of Drummond 2008 formula 6.

Parameters
rInter-particle separation vector.
aReal-space cell axes.
tolTolerance for the Ewald pair interaction in Ha.

Definition at line 292 of file EwaldRef.cpp.

References qmcplusplus::abs(), qmcplusplus::det(), getKappaEwald(), gridSum(), qmcplusplus::inverse(), qmcplusplus::pow(), qmcplusplus::sqrt(), and qmcplusplus::transpose().

Referenced by ewaldEnergy().

293 {
294  // Real-space cell volume
295  real_t volume = std::abs(det(a));
296  // k-space cell axes
297  RealMat b = 2 * M_PI * transpose(inverse(a));
298  // k-space cutoff (kappa)
299  real_t kconv = getKappaEwald(volume);
300 
301  // Set constants for real-/k-space Ewald pair functors
302  real_t rconst = 1. / (std::sqrt(2.) * kconv);
303  real_t kconst = -std::pow(kconv, 2) / 2;
304  real_t kfactor = 4 * M_PI / volume;
305 
306  // Create real-/k-space fuctors for terms within the sums in formula 6
307  RspaceEwaldTerm rfunc(r, a, rconst);
308  KspaceEwaldTerm kfunc(r, b, kconst, kfactor);
309 
310  // Compute the constant term
311  real_t cval = -2 * M_PI * std::pow(kconv, 2) / volume;
312  // Compute the real-space sum (includes zero)
313  real_t rval = gridSum(rfunc, true, tol);
314  // Compute the k-space sum (excludes zero)
315  real_t kval = gridSum(kfunc, false, tol);
316 
317  // Sum all contributions to get the Ewald pair interaction
318  real_t es = cval + rval + kval;
319 
320  return es;
321 }
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Definition: TensorOps.h:838
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
Tensor< real_t, DIM > RealMat
Type for floating point matrices of shape DIM,DIM.
Definition: EwaldRef.h:50
real_t gridSum(T &function, bool zero=true, real_t tol=1e-11)
Perform a sum over successively larger cubic integer grids in DIM dimensional space for arbitrary fun...
Definition: EwaldRef.cpp:140
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
real_t getKappaEwald(real_t volume)
Find the optimal kappa for Ewald pair sums.
Definition: EwaldRef.cpp:275
AntiSymTensor< T, D > transpose(const AntiSymTensor< T, D > &rhs)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
Tensor< T, D > inverse(const Tensor< T, D > &a)
Definition: TensorOps.h:879
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44

◆ getKappaEwald()

real_t qmcplusplus::ewaldref::getKappaEwald ( real_t  volume)

Find the optimal kappa for Ewald pair sums.

The optimal kappa balances the number of points within a given isosurface of the Gaussians (or limiting Gaussians from erfc) in the real-space and k-space Ewald pair terms. The balancing condition is made under isotropic assumptions, as reflected by the use of a sphere equal in volume to the simulation cell to determine the radius.

Parameters
volumeVolume of the real space cell.

Definition at line 275 of file EwaldRef.cpp.

References qmcplusplus::pow(), and qmcplusplus::sqrt().

Referenced by ewaldSum().

276 {
277  real_t radius = std::pow(3. * volume / (4 * M_PI), 1. / 3);
278  return radius / std::sqrt(2 * M_PI);
279 }
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44

◆ getKappaMadelung()

real_t qmcplusplus::ewaldref::getKappaMadelung ( real_t  volume)

Find the optimal kappa for Madelung sums.

The optimal kappa balances the number of points within a given isosurface of the Gaussians (or limiting Gaussians from erfc) in the real-space and k-space Madelung terms. The balancing condition is made under isotropic assumptions, as reflected by the use of a sphere equal in volume to the simulation cell to determine the radius.

Parameters
volumeVolume of the real space cell.

Definition at line 217 of file EwaldRef.cpp.

References qmcplusplus::pow(), and qmcplusplus::sqrt().

Referenced by madelungSum().

218 {
219  real_t radius = std::pow(3. * volume / (4 * M_PI), 1. / 3);
220  return std::sqrt(M_PI) / radius;
221 }
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44

◆ gridSum()

real_t qmcplusplus::ewaldref::gridSum ( T &  function,
bool  zero = true,
real_t  tol = 1e-11 
)

Perform a sum over successively larger cubic integer grids in DIM dimensional space for arbitrary functors.

Parameters
functionA functor accepting a point in the grid and returning the real-valued contribution to the sum from that point.
zeroInclude the origin in the sum (or not).
tolTolerance for the sum. Summation ceases when the contribution to the sum from the outermost cubic shell of points is less than tol.

Definition at line 140 of file EwaldRef.cpp.

References qmcplusplus::abs().

Referenced by ewaldSum(), and madelungSum().

141 {
142  real_t dv = std::numeric_limits<real_t>::max();
143  real_t dva = std::numeric_limits<real_t>::max();
144  real_t v = 0.0;
145  int_t im = 0;
146  int_t jm = 0;
147  int_t km = 0;
148  IntVec iv;
149  // Add the value at the origin, if requested.
150  if (zero)
151  {
152  iv = 0;
153  v += function(iv);
154  }
155  // Sum over cubic surface shells until the tolerance is reached.
156  while (std::abs(dva) > tol)
157  {
158  dva = 0.0;
159  dv = 0.0; // Surface shell contribution.
160  // Sum over new surface planes perpendicular to the x direction.
161  im += 1;
162  for (int_t i : {-im, im})
163  for (int_t j = -jm; j < jm + 1; ++j)
164  for (int_t k = -km; k < km + 1; ++k)
165  {
166  iv[0] = i;
167  iv[1] = j;
168  iv[2] = k;
169  real_t f = function(iv);
170  dv += f;
171  dva += std::abs(f);
172  }
173  // Sum over new surface planes perpendicular to the y direction.
174  jm += 1;
175  for (int_t j : {-jm, jm})
176  for (int_t k = -km; k < km + 1; ++k)
177  for (int_t i = -im; i < im + 1; ++i)
178  {
179  iv[0] = i;
180  iv[1] = j;
181  iv[2] = k;
182  real_t f = function(iv);
183  dv += f;
184  dva += std::abs(f);
185  }
186  // Sum over new surface planes perpendicular to the z direction.
187  km += 1;
188  for (int_t k : {-km, km})
189  for (int_t i = -im; i < im + 1; ++i)
190  for (int_t j = -jm; j < jm + 1; ++j)
191  {
192  iv[0] = i;
193  iv[1] = j;
194  iv[2] = k;
195  real_t f = function(iv);
196  dv += f;
197  dva += std::abs(f);
198  }
199  v += dv;
200  }
201 
202  return v;
203 }
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
TinyVector< int_t, DIM > IntVec
Type for integer vectors of length DIM.
Definition: EwaldRef.h:46
int int_t
Type for integers.
Definition: EwaldRef.h:42
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44

◆ madelungSum()

real_t qmcplusplus::ewaldref::madelungSum ( const RealMat a,
real_t  tol = 1e-10 
)

Compute the Madelung constant to a given tolerance.

Corresponds to the entirety of Drummond 2008 formula 7.

Parameters
aReal-space cell axes.
tolTolerance for the Madelung constant in Ha.

Definition at line 232 of file EwaldRef.cpp.

References qmcplusplus::abs(), qmcplusplus::det(), getKappaMadelung(), gridSum(), qmcplusplus::inverse(), qmcplusplus::Units::time::ms, qmcplusplus::pow(), qmcplusplus::sqrt(), and qmcplusplus::transpose().

Referenced by ewaldEnergy().

233 {
234  // Real-space cell volume
235  real_t volume = std::abs(det(a));
236  // k-space cell axes
237  RealMat b = 2 * M_PI * transpose(inverse(a));
238  // k-space cutoff (kappa)
239  real_t kconv = getKappaMadelung(volume);
240 
241  // Set constants for real-/k-space Madelung functors
242  real_t rconst = kconv;
243  real_t kconst = -1. / (4 * std::pow(kconv, 2));
244  real_t kfactor = 4 * M_PI / volume;
245 
246  // Create real-/k-space fuctors for terms within the sums in formula 7
247  RspaceMadelungTerm rfunc(a, rconst);
248  KspaceMadelungTerm kfunc(b, kconst, kfactor);
249 
250  // Compute the constant term
251  real_t cval = -M_PI / (std::pow(kconv, 2) * volume) - 2 * kconv / std::sqrt(M_PI);
252  // Compute the real-space sum (excludes zero)
253  real_t rval = gridSum(rfunc, false, tol);
254  // Compute the k-space sum (excludes zero)
255  real_t kval = gridSum(kfunc, false, tol);
256 
257  // Sum all contributions to get the Madelung constant
258  real_t ms = cval + rval + kval;
259 
260  return ms;
261 }
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Definition: TensorOps.h:838
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
Tensor< real_t, DIM > RealMat
Type for floating point matrices of shape DIM,DIM.
Definition: EwaldRef.h:50
real_t gridSum(T &function, bool zero=true, real_t tol=1e-11)
Perform a sum over successively larger cubic integer grids in DIM dimensional space for arbitrary fun...
Definition: EwaldRef.cpp:140
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
real_t getKappaMadelung(real_t volume)
Find the optimal kappa for Madelung sums.
Definition: EwaldRef.cpp:217
AntiSymTensor< T, D > transpose(const AntiSymTensor< T, D > &rhs)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
Tensor< T, D > inverse(const Tensor< T, D > &a)
Definition: TensorOps.h:879
double real_t
Type for floating point numbers.
Definition: EwaldRef.h:44