Electrostatics
UAMMD implements fast spectral solvers for the Poisson equation with Gaussian sources of charge with arbitrary widths centered at the particles’ locations. Two solvers are available with triply or doubly periodic boundary conditions.
In general, we want to solve the Poisson equation in a periodic domain in the presence of a charge density ,
Here represents the permittivity of the medium and
accounts for
Gaussian charges of strength
located at
,
Let us denote with the vector containing all charges as .
We will use the spreading operator,
, (see Immersed Boundary Method) to transform the particles charges to a smooth charge density field. We use the Gaussian kernel,
Identifying as the width the charges (notice that the case
corresponds to point charges).
Once the Poisson equation is solved we have the value of the potential in every point in space and can be evaluated at the charges locations via the interpolation operator (see Immersed Boundary Method).
Here represents the interpolation operator, that averages a quantity defined in space to a charge’s location.
The electrostatic energy can be computed as
In a similar way we compute the electrostatic force, , acting on each charge from the electric field
Interpolating again we get
Thus, the electrostatic force acting on particle is
Given that the Gaussian kernel has, in principle, an infinite support evaluating the charge density at every point in space, as well as computing the averages of the electric potential and field at the particles’ locations can be highly inefficient. In practice we overcome this limitation by truncating the Gaussian kernel at a certain distance according to a desired tolerance.
Triply periodic boundary conditions
In this instance we solve the Poisson equation with in a periodic boundary (in the three dimensions). Our approach is similar to the one presented at [1]. However, the authors of [1] make use of the so-called Fast Gaussian Gridding (FGG) to accelerate spreading/interpolation while UAMMD’s its Immersed Boundary framework. The electrostatic modules in UAMMD make use of Ewald splitting framework following closely from the mathematical machinery laid out in [2]. One notable thing about the following algorithm is that it can be seen as merely a reinterpretation of terms in the non-fluctuating version of the Force Coupling Method for hydrodynamics.
We solve the Poisson equation in Fourier space by convolution with the Poisson’s Greens function,
We can reuse the methodological machinery devised for the Force Coupling Method.
The electric field can be derived from the potential in fourier space via ik differentiation,
This equation can be discretized using a 3D FFT in a grid with spacing fine enough to resolve the Gaussian charges.
- The whole algorithm, going from particle charges to forces, can be summarized as follows
Spread charges to the grid,
.
Fourier transform
.
Multiply by the Poisson’s Greens function to obtain the potential,
.
Compute field via ik differentiation,
.
Transform potential and field back to real space
;
.
Interpolate energy and/or force to charge locations,
;
.
The grid size is coupled to the Gaussian charge width, hindering the simulation of systems with narrow charges or large domains. UAMMD’s implementation has an Ewald splitting mode to overcome this limitation.
Without getting into too much detail (see [2]), we can write the potential as
where represents convolution and the intermediate solution
satisfies
The splitting function is defined as
Here the splitting parameter, , is an arbitrary factor that is chosen to optimize performance.
Given that the Laplacian commutes with the convolution we can divide the problem in two separate parts, denoted as near and far field
The convolution of two Gaussians is also a Gaussian, so in the case of the far field the RHS results in wider Gaussian sources that can be interpreted as smeared versions of the original ones. The far field RHS thus decays exponentially in Fourier space and is solved as in the non Ewald split case. On the other hand the near field resulting charges are sharply peaked and more compactly supported than the originals, furthermore integrating to zero in 3D. The near field Green’s function is computed analytically in real space and evaluated for each pair of particles inside a given radius (that is controlled by the desired tolerance). The electric field is computed by analytically differentiating and evaluating this Green’s function. For a given tolerance, the splitting parameters controls the load that each part of the algorithm takes. In each case there will be an optimal split that gives the best performance.
Usage
The triply periodic Poisson solver is available as an Interactor called Poisson.
- The following parameters are available:
Box boxSimulation domain (must be triply periodic).real epsilonPermittivity.real gwGaussian width of the charges (all charges have the same width).real toleranceOverall tolerance of the algorithm.real split = 0The splitting parameter,, for the Ewald mode. If it is equal to 0 the non-Ewald split mode is used.
#include<uammd.cuh>
#include<Interactor/SpectralEwaldPoisson.cuh>
using namespace uammd;
//Creates and returns a triply periodic Poisson solver Interactor
auto createTPPoissonInteractor(std::shared_ptr<ParticleData> pd){
Poisson::Parameters par;
par.box = Box({128, 128, 128});
//Permittivity
par.epsilon = 1.0;
//Gaussian width of the sources
par.gw = 1.0;
//Overall tolerance of the algorithm
par.tolerance = 1e-4;
//If a splitting parameter is passed
// the code will run in Ewald split mode
//Otherwise, the non Ewald version will be used
//par.split = 1.0;
return std::make_shared<Poisson>(pd, par);
}
Here, pd is a ParticleData instance.
Hint
A ParticleGroup can be provided instead of a ParticleData for the module to act only on a subset of particles.
Note
As usual, this Interactor can be added to an Integrator.
Note
The tolerance is the maximum relative error allowed in the potential for two charges. The potential for L->inf is extrapolated and compared with the analytical solution. Also in Ewald split mode the relative error between two different splits is less than the tolerance. See test/Potential/Poisson
Doubly periodic boundary conditions
We want to solve the Poisson equation with the following set of boundary conditions for the potential
And for the electric field
We introduce, via these BCs, the possibility of having arbitrary surface charges at the walls, and
for the bottom and top respectively. Additionally, we can set different permittivities inside the slab (
) above (
) and below (
) it.
Finally, we assume that the domain is overall electroneutral,
We impose that the sources do not overlap the boundaries in the direction,
, so that the charge density integrates to one inside the slab. Given that the Gaussian is not compactly supported we truncate it at
to overcome this, ensuring that the integral is at least
of the charge
.
The approach to solve the set of equations above is wildly different from the triply periodic case, a complete description of the algorithm can be found in [3]. In short, we use a grid-based solver as in the triply periodic case and make use of Ewald splitting, the main difference now is that we work in a Fourier-Chebyshev space instead of just Fourier.
Usage
The creation of the Doubly Periodic Poisson Interactor is similar to that of the triply periodic case. With the exception that now the box size is communicated separately in the parallel and perpendicular directions and the permittivity can be different inside and outside the domain. Besides the parameters in the source code example below, additional ones are available to fine-tune several internal precision parameters (such as support, upsampling or overall tolerance). By default, the module will provide an overall tolerance of around 4 digits, which is the study case in the original work describing the doubly periodic algorithm [3]. Additionally, a special functor can be provided specifying the surface charges.
In all instances, the surface charge will enforce overall electroneutrality inside the domain. For instance, if a single positive charge of strength is located inside the domain, each wall will be assigned a constant charge of
.
- The following parameters are available:
real LxySimulation domain size in the plane.real HDomain height ().
DPPoissonSlab::Permitivity permPermittivity in the three domains, contains a top, bottom and inside members.real gwGaussian width of the charges (all charges have the same width).real split = 0The splitting parameter,, for the Ewald mode. If it is equal to 0 the non-Ewald split mode is used.
std::shared_ptr<SurfaceChargeDispatch> surfaceChargeAn object providing the surface charge, see below.
- Additionally, some optional/advanced parameters are available:
int NxyInstead of the splitting parameter the number of cells for the far field can be specified.int supportNumber of support cells for the Gaussian kernel.real numberStandardDeviationsabove, number of standard deviations to truncate the Gaussian kernel at.
real toleranceControls the cut off distance of the near field Green’s function.
#include<Interactor/DoublyPeriodic/DPPoissonSlab.cuh>
using namespace uammd;
auto createDPPoissonInteractor(std::shared_ptr<ParticleData> pd){
DPPoissonSlab::Parameters par;
par.Lxy = 128;
par.H = 10; //Domain height
DPPoissonSlab::Permitivity perm;
perm.inside = 1.0;
perm.top = 1.0;
perm.bottom = 1.0;
par.permitivity = perm;
par.gw = 1.0; //Width of the Gaussian sources
par.split = gw*0.1; //Splitting parameter
auto poisson = make_shared<DPPoissonSlab>(pd, par);
return poisson;
}
Hint
The doubly periodic electrostatic Interactor does not accept an overall tolerance parameter. The accuracy is defaulted to provide a relative error around 1e-3. Advanced users can refer to [3] to tune the advanced parameters to achieve more accuracy.
Here, pd is a ParticleData instance.
Hint
A ParticleGroup can be provided instead of a ParticleData for the module to act only on a subset of particles.
Note
As usual, this Interactor can be added to an Integrator.
Note
A set of examples showcasing this implementation can be found at https://github.com/stochasticHydroTools/DPPoissonTests , which can be used to reproduce the results in [3].
Providing the surface charges
The surface charge parameter in the DPPoisson module must inherit from the type DPPoissonSlab_ns::SurfaceChargeDispatch.
-
class DPPoissonSlab_ns::SurfaceChargeDispatch
Example
A constant surface charge dispatcher.
#include<Interactor/DoublyPeriodic/DPPoissonSlab.cuh>
using namespace uammd;
struct ConstantSurfaceCharge: public DPPoissonSlab_ns::SurfaceChargeDispatch{
real top(real x, real y) override{ return 1.0;}
real bottom(real x, real y) override{ return -1.0;}
};
References: