Atomic density

class featomic.density.DiracDelta(*, center_atom_weight: float = 1.0, scaling: RadialScaling | None = None)

Bases: AtomicDensity

Delta atomic densities of the form \(g(r)=\delta(r)\).

Parameters:
  • center_atom_weight – in density expansion, the central atom sees its own density, and is in this sense its own neighbor. Setting this weight to 0 allows to disable this behavior and only expand the density of actual neighbors.

  • scaling – optional radial scaling function. If this is left to None, no radial scaling is applied.

class featomic.density.Gaussian(*, width: float, center_atom_weight: float = 1.0, scaling: RadialScaling | None = None)

Bases: AtomicDensity

Gaussian atomic density function.

In featomic, we use the convention

\[g(r) = \frac{1}{(\pi \sigma^2)^{3/4}}e^{-\frac{r^2}{2\sigma^2}} \,.\]

The prefactor was chosen such that the “L2-norm” of the Gaussian

\[\|g\|^2 = \int \mathrm{d}^3\boldsymbol{r} |g(r)|^2 = 1\,,\]

The derivatives of the Gaussian atomic density with respect to the position is

\[g^\prime(r) = \frac{\partial g(r)}{\partial r} = \frac{-r}{\sigma^2(\pi \sigma^2)^{3/4}}e^{-\frac{r^2}{2\sigma^2}} \,.\]
Parameters:
  • width – Width of the atom-centered gaussian used to create the atomic density

  • center_atom_weight – in density expansion, the central atom sees its own density, and is in this sense its own neighbor. Setting this weight to 0 allows to disable this behavior and only expand the density of actual neighbors.

  • scaling – optional radial scaling function. If this is left to None, no radial scaling is applied.

class featomic.density.SmearedPowerLaw(*, smearing: float, exponent: int, center_atom_weight: float = 1.0, scaling: RadialScaling | None = None)

Bases: AtomicDensity

Smeared power law density, as used in LODE.

This is a smooth, differentiable density that behaves like \(1 / r^p\) as \(r\) goes to infinity.

It is defined as

\[g(r) = \frac{1}{\Gamma\left(\frac{p}{2}\right)} \frac{\gamma\left( \frac{p}{2}, \frac{r^2}{2\sigma^2} \right)} {r^p},\]

where \(p\) is the potential exponent, \(\Gamma(z)\) is the Gamma function and \(\gamma(a, x)\) is the incomplete lower Gamma function.

For more information about the derivation of this density, see https://doi.org/10.1021/acs.jpclett.3c02375 and section D of the supplementary information.

Parameters:
  • smearing – Smearing used to remove the singularity at 0 (\(\sigma\) above)

  • exponent – Potential exponent of the decorated atom density (\(p\) above)

  • center_atom_weight – in density expansion, the central atom sees its own density, and is in this sense its own neighbor. Setting this weight to 0 allows to disable this behavior and only expand the density of actual neighbors.

  • scaling – optional radial scaling function. If this is left to None, no radial scaling is applied.

class featomic.density.AtomicDensity(*, center_atom_weight: float = 1.0, scaling: RadialScaling | None = None)

Base class representing atomic densities.

You can inherit from this class to define new custom densities, implementing compute() accordingly. If the new density has corresponding hyper parameters in the native calculators, you should also implement get_hypers().

All atomic densities are assumed to be invariant under rotation, and as such only defined as a function of the distance to the origin.

The overall density around a central atom is the sum of the central atom’s neighbors density, with some optional radial scaling.

\[\rho_i(r) = \sum_j \text{scaling}(r_{ij}) \; g_j(r - r_{ij})\]

where \(\text{scaling}(r)\) is the scaling function, \(g_j\) the density coming from neighbor \(j\), and \(r_{ij}\) the distance between the center \(i\) and neighbor \(j\).

Parameters:
  • center_atom_weight – in density expansion, the central atom sees its own density, and is in this sense its own neighbor. Setting this weight to 0 allows to disable this behavior and only expand the density of actual neighbors.

  • scaling – optional radial scaling function. If this is left to None, no radial scaling is applied.

abstract compute(positions: ndarray, *, derivative: bool) ndarray

Compute the density (or it’s derivative) around a single atom.

The atom is located at position=0 and the density is computed on multiple grid points at the given positions. The computed density does not include any radial scaling or central atom weighting.

Parameters:
  • positions – positions of grid point where to evaluate the atomic density

  • derivative – should this function return the values or the derivatives of the density?

Returns:

evaluated atomic density on the grid

get_hypers()

Return the native hyper parameters corresponding to this atomic density


class featomic.density.Willatt2018(*, exponent: int, rate: float, scale: float)

Bases: RadialScaling

Radial density scaling as proposed in https://doi.org/10.1039/C8CP05921G by Willatt et. al.

\[\text{scaling}(r) = \frac{c}{c + \left(\frac{r}{r_0}\right) ^ m}\]
Parameters:
  • exponent\(m\) in the formula above

  • rate\(c\) in the formula above

  • scale\(r_0\) in the formula above

class featomic.density.RadialScaling

Base class representing radial scaling of atomic densities.

You can inherit from this class to define new custom radial scaling, implementing compute() accordingly. If the new radial scaling has corresponding hyper parameters in the native calculators, you should also implement get_hypers().

get_hypers()

Return the native hyper parameters corresponding to this atomic density scaling

abstract compute(positions: ndarray, *, derivative: bool) ndarray

Compute the scaling function (or it’s derivative) on grid points at the given positions.

Parameters:
  • positions – positions of grid point where to evaluate the radial scaling

  • derivative – should this function return the values or the derivatives of the radial scaling?

Returns:

evaluated radial scaling function