InteratomicPotentials.jl
This repository implements some basic language and syntax for manipulating interatomic potentials in Julia. The primary purpose of this package is to design a flexible package for use with datadriven and parameterfitted interatomic potentials. This package is also being designed in order to allow users to define custom potentials and forces for use in molecular dynamics.
This package is part of the CESMIX molecular modeling suite. This package is also intended to be used with Atomistic.jl (for molecular dynamics, with Molly.jl), InteratomicBasisPotentials.jl (for machine learning potentials like SNAP and ACE), and PotentialLearning.jl (for fitting potentials from data).
This package is a work in progress.
Working Example
In order to compute the interatomic energy of a system, or the forces between atoms in a system, the user has to

 define an
AbstractSystem
usingAtomsBase
and
 define an

 construct a potential (subtype of an ArbitraryPotential).
Once these two structures have ben instantiated, the quantity of interest can be computed using the signature func(system, potential)
.
First, let's create a configuration:
using InteratomicPotentials, StaticArrays
using AtomsBase, Unitful, UnitfulAtomic
# Define an atomic system
elem = :Ar
atom1 = Atom(elem, ( @SVector [1.0, 0.0, 0.0] ) * 1u"Å")
atom2 = Atom(elem, ( @SVector [1.0, 0.25, 0.0] ) * 1u"Å")
atoms = [atom1,atom2]
box = [[1., 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] * 1u"Å"
bcs = [DirichletZero(), Periodic(), Periodic()]
system = FlexibleSystem(atoms, box , bcs)
Now we can define the parameters of our interatomic potential:
ϵ = 1.0 * 1u"eV"
σ = 0.25 * 1u"Å"
rcutoff = 2.25 * 1u"Å"
lj = LennardJones(ϵ, σ, rcutoff, [elem]) # <: EmpiricalPotential <: AbstractPotential
Now we can compute a variety of quantities of the system:
pe = potential_energy(system, lj) # <: Float64 (Hartree)
f = force(system, lj) # <: Vector{SVector{3, Float64}} (Hartree/Bohr)
v = virial(system, lj) # <: Float64 (Hartree)
v_tensor = virial_stress(system, lj) # <: SVector{6, Float64} (Hartree)
When computing the force, the energy is already available. A convenience implementation that returns both quantities is given by:
pe, f = energy_and_force(system, lj)
See "/test/" for further examples.
Utility functions
There are a growing number of features designed to allow handle of potential parameter easier. For example, one can retrieve the parameters of a potential via:
get_rcutoff(lj) # Gets radial cutoff (here: 2.25 * 1u"Angstrom")
get_species(lj) # Returns the species the potential is defined for (here: [:Ar])
get_parameters(lj) # Returns the parameters (here: [ϵ, σ])
set_parameters(lj, (ϵ = 2.0 * 1u"eV", σ = 1.0 * 1u"Å")) # Set parameters (returns a new potential)
Potential Types
All interatomic potentials listed in this project are subtypes of ArbitraryPotential
. At this point, as of v2.0, there are two branches of potentials: EmpiricalPotential
and MixedPotentials
. A sister package, julia InteratomicBasisPotentials.jl
defines a potential called BasisPotential
, see that package for additional details.
EmpiricalPotential
s include twobody potentials like BornMayer
, LennardJones
. MixedPotential
is a convenience type for allowing the linear combination of potentials. An example would be:
lj1 = LennardJones(1.0 * u"eV", 1.0 * u"Angstrom", 2.5 * u"Angstrom", [:Ar]) # ArAr Interactions
lj2 = LennardJones(1.0 * u"eV", 1.5 * u"Angstrom", 3.0 * u"Angstrom", [:Xe]) # XeXe Interactions
lj3 = LennardJones(1.5 * u"eV", 1.3 * u"Angstrom", 2.5 * u"Angstrom", [:Ar, :Xe]) # ArXe Interactions
lj = lj1 + lj2 + lj3# Potential defined for all interactions in an ArXe system.
EmpiricalPotential <: AbstractPotential
BornMayer <: EmpiricalPotential
LennardJones <: EmpiricalPotential
Coulomb <: EmpiricalPotential
ZBL <: EmpiricalPotential
LinearCombinationPotential <: MixedPotential
# See InteratomicBasisPotentials.jl
BasisPotential <: AbstractPotential
SNAP <: BasisPotential
ACE <: BasisPotential