Ewald summation in periodic systems¶
In 3D periodic solids the Coulomb series \(\sum_{g,A,B} Z_A Z_B / |R_{AB} + g|\)
is conditionally convergent: different truncation shapes give
different answers. The standard fix is Ewald summation, which splits
each \(1/r\) term into a short-range part (evaluated in real space, where
it converges exponentially) plus a long-range part (evaluated in
reciprocal space, where the Gaussian damping makes the sum converge
fast too). vibe-qc’s periodic Coulomb treatment is being built up in
three sub-phases; today’s main branch has the first two shipped.
Dispatch — CoulombMethod¶
Every LatticeSumOptions has a coulomb_method field that selects how
1/r lattice sums are evaluated:
from vibeqc import LatticeSumOptions, CoulombMethod
opts = LatticeSumOptions()
opts.coulomb_method = CoulombMethod.DIRECT_TRUNCATED # default
# or:
opts.coulomb_method = CoulombMethod.EWALD_3D # quantitative 3D
Enum value |
Meaning |
Status |
|---|---|---|
|
Half-summed direct truncation. Default. Exact in the molecular-limit regime (large unit cell, cutoff excludes all non-zero cells). Conditionally convergent in 3D bulk. |
Works for all sums (molecular-limit correctness) |
|
Ewald summation under the tin-foil + jellium convention. Unconditionally convergent. |
Nuclear repulsion: ✅ shipped (Phase 12e-a) |
|
2D slab Ewald. |
Not yet implemented |
|
1D line with neutralising background. |
Not yet implemented |
Phase 12e-a: nuclear-nuclear Ewald (shipped)¶
The Madelung energy
(primed sum excludes the \(A = B, g = 0\) term) becomes unconditionally convergent under Ewald summation with the tin-foil boundary convention:
where:
\(E_{\text{real}} = \tfrac{1}{2} \sum_{A,B} {\sum_{g}}' Z_A Z_B \cdot \operatorname{erfc}(\alpha \, r) / r\) — exponentially convergent real-space sum.
\(E_{\text{recip}} = \tfrac{2\pi}{V} \sum_{G \neq 0} |S(G)|^2 \, e^{-|G|^2/(4\alpha^2)} / |G|^2\) — k-space sum with Gaussian damping. \(S(G) = \sum_A Z_A \, e^{iG \cdot R_A}\) is the nuclear structure factor.
\(E_{\text{self}} = -(\alpha/\sqrt{\pi}) \sum_A Z_A^2\) — removes the spurious self-interaction from each nucleus’s Gaussian-smeared image.
\(E_{\text{bg}} = -(\pi/(2 \alpha^2 V)) (\sum_A Z_A)^2\) — background correction for a non-neutral cell (the “jellium” prescription).
The Ewald parameter \(\alpha\) can be set explicitly or auto-derived from
a real-space cutoff so that erfc\((\alpha R_{\text{cut}}) \approx\) tolerance.
Usage (low-level)¶
For an arbitrary 3D lattice of point charges:
import numpy as np
from vibeqc import EwaldOptions, ewald_point_charge_energy
# NaCl-like rocksalt with ±1 charges
a = 5.6 / 0.529177210903 # 5.6 Å in bohr
lattice = 0.5 * a * np.array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]], dtype=float).T
positions = np.column_stack([[0, 0, 0],
[0.5 * a, 0, 0]])
charges = np.array([+1.0, -1.0])
opts = EwaldOptions()
opts.real_cutoff_bohr = 30.0 # auto-derive α and recip cutoff
energy = ewald_point_charge_energy(lattice, positions, charges, opts)
print(f"NaCl Madelung / pair: {energy:.8f} Ha (expected -0.330275485)")
Usage (through nuclear_repulsion_per_cell)¶
For a real periodic SCF, route through LatticeSumOptions.coulomb_method:
import numpy as np
from vibeqc import (
Atom, PeriodicSystem, LatticeSumOptions, CoulombMethod,
nuclear_repulsion_per_cell,
)
a = 5.6 / 0.529177210903
lattice = 0.5 * a * np.array([[0, 1, 1],
[1, 0, 1],
[1, 1, 0]], dtype=float).T
sysp = PeriodicSystem(
dim=3, lattice=lattice,
unit_cell=[Atom(11, [0, 0, 0]),
Atom(17, [0.5 * a, 0, 0])],
)
opts = LatticeSumOptions()
opts.coulomb_method = CoulombMethod.EWALD_3D
opts.nuclear_cutoff_bohr = 30.0
print(nuclear_repulsion_per_cell(sysp, opts))
Choosing cutoffs and \(\alpha\)¶
If you pass only
real_cutoff_bohr, \(\alpha\) and the reciprocal cutoff are chosen automatically to achievetolerance(default1e-12) in both sums.If you pass an explicit
alpha, use a larger real cutoff or the real-space sum may not converge.Final energy is independent of \(\alpha\) to the specified tolerance — this is the primary correctness test of any Ewald implementation. vibe-qc’s test suite verifies it explicitly for NaCl, CsCl, ZnS, and simple-cubic jellium.
Phase 12e-b: erfc-screened nuclear attraction (building block)¶
compute_nuclear_erfc_lattice(basis, system, omega, options) returns
the short-range component of \(V(g)\):
At \(\omega \to 0\) this reduces to the ordinary 1/r nuclear attraction
(compute_nuclear_lattice); at finite \(\omega > 0\) it is exponentially
convergent as a real-space lattice sum. This is the plumbing 12e-c will
combine with a reciprocal-space long-range piece to provide the full
\(\text{EWALD\_3D}\) treatment of \(V(g)\).
from vibeqc import compute_nuclear_erfc_lattice, LatticeSumOptions
opts = LatticeSumOptions()
opts.cutoff_bohr = 15.0
opts.nuclear_cutoff_bohr = 25.0
V_erfc = compute_nuclear_erfc_lattice(basis, system, omega=0.3, opts)
Today this function is primarily useful for tests and for users exploring Ewald internals — the SCF drivers do not call it yet. Until 12e-c lands, the default path (direct-truncated V) remains correct in the molecular limit and accurate-enough-for-qualitative in genuine 3D bulk; quantitative 3D results arrive with 12e-c.
Phase 12e-c: full Gaussian-charge Ewald (pending)¶
The long-range parts of both the nuclear attraction \(V(g)\) and the electron-repulsion integrals \((\mu\nu | \lambda\sigma)\) are smooth Gaussian-smeared potentials; their matrix elements fold as reciprocal- space sums involving the Fourier transform of Gaussian AO pairs. The planned implementation follows the standard Saunders–Dovesi multipolar splitting used in CRYSTAL:
Near field (nuclei / AO pairs within a short-range cutoff of each other): compute exact integrals, no multipole expansion.
Far field: expand the charge distribution in a multipole series (monopole + dipole + quadrupole typically sufficient) and Ewald-sum the multipoles in reciprocal space. The long-range tail converges exponentially in \(|G|\).
This phase also adds FFTW3 as a build-time dependency to accelerate the reciprocal-space grid sums. Until it ships, 3D bulk calculations with EWALD_3D are limited to the nuclear-repulsion piece — sufficient to validate Madelung constants and correctly compute total energies in the molecular-limit regime, but not yet to give quantitative bulk SCF energies.
References¶
P. P. Ewald, Ann. Phys. 64, 253 (1921). Original Ewald paper.
V. R. Saunders, C. Freyria-Fava, R. Dovesi, L. Salasco, C. Roetti, Mol. Phys. 77, 629 (1992). Multipolar splitting used in CRYSTAL.
A. Y. Toukmaji, J. A. Board Jr., Comp. Phys. Commun. 95, 73 (1996). Modern Ewald review.
M. P. Allen, D. J. Tildesley, Computer Simulation of Liquids, 2nd ed., Oxford, 2017. Clear textbook treatment with the \(\alpha\) auto-tuning formula vibe-qc uses.