[docs]classCoulombPotential(Potential):""" Smoothed electrostatic Coulomb potential :math:`1/r`. Here :math:`r` is the inter-particle distance It can be used to compute: 1. the full :math:`1/r` potential 2. its short-range (SR) and long-range (LR) parts, the split being determined by a length-scale parameter (called "Inverse" in the code) 3. the Fourier transform of the LR part :param smearing: float or torch.Tensor containing the parameter often called "sigma" in publications, which determines the length-scale at which the short-range and long-range parts of the naive :math:`1/r` potential are separated. The smearing parameter corresponds to the "width" of a Gaussian smearing of the particle density. :param exclusion_radius: A length scale that defines a *local environment* within which the potential should be smoothly zeroed out, as it will be described by a separate model. """def__init__(self,smearing:Optional[float]=None,exclusion_radius:Optional[float]=None,):super().__init__(smearing,exclusion_radius)
[docs]deffrom_dist(self,dist:torch.Tensor)->torch.Tensor:""" Full :math:`1/r` potential as a function of :math:`r`. :param dist: torch.tensor containing the distances at which the potential is to be evaluated. """return1.0/dist
[docs]deflr_from_dist(self,dist:torch.Tensor)->torch.Tensor:""" Long range of the range-separated :math:`1/r` potential. Used to subtract out the interior contributions after computing the LR part in reciprocal (Fourier) space. :param dist: torch.tensor containing the distances at which the potential is to be evaluated. """ifself.smearingisNone:raiseValueError("Cannot compute long-range contribution without specifying `smearing`.")returntorch.erf(dist/self.smearing/2.0**0.5)/dist
[docs]deflr_from_k_sq(self,k_sq:torch.Tensor)->torch.Tensor:r""" Fourier transform of the LR part potential in terms of :math:`\mathbf{k^2}`. :param k_sq: torch.tensor containing the squared lengths (2-norms) of the wave vectors k at which the Fourier-transformed potential is to be evaluated """ifself.smearingisNone:raiseValueError("Cannot compute long-range kernel without specifying `smearing`.")# avoid NaNs in backward, see# https://github.com/jax-ml/jax/issues/1052# https://github.com/tensorflow/probability/blob/main/discussion/where-nan.pdfmasked=torch.where(k_sq==0,1.0,k_sq)returntorch.where(k_sq==0,0.0,4*torch.pi*torch.exp(-0.5*self.smearing**2*masked)/masked,)
[docs]defself_contribution(self)->torch.Tensor:# self-correction for 1/r potentialifself.smearingisNone:raiseValueError("Cannot compute self contribution without specifying `smearing`.")return(2/torch.pi)**0.5/self.smearing
[docs]defbackground_correction(self)->torch.Tensor:# "charge neutrality" correction for 1/r potentialifself.smearingisNone:raiseValueError("Cannot compute background correction without specifying `smearing`.")returntorch.pi*self.smearing**2