Skip to content

Commit

Permalink
Merge pull request #50 from cesmix-mit/IP_IBP
Browse files Browse the repository at this point in the history
Merge InteratomicBasisPotentials.jl into InteratomicPotentials.jl + Updates from PotentialLearning.jl
  • Loading branch information
emmanuellujan committed Jan 4, 2024
2 parents 7ce2df9 + adc4b1a commit 973e0d5
Show file tree
Hide file tree
Showing 52 changed files with 3,547 additions and 95 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
9 changes: 7 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ jobs:
fail-fast: false
matrix:
version:
- "1.6"
- "nightly"
- "1.9"
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
steps:
- name: Windows git setup
if: runner.os == 'Windows'
run:
git config --global core.autocrlf false
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
Expand All @@ -43,6 +46,8 @@ jobs:
using Pkg
Pkg.Registry.add("General")
Pkg.Registry.add(RegistrySpec(url = "https://github.com/cesmix-mit/CESMIX.git"))
Pkg.Registry.add(RegistrySpec(url = "https://github.com/JuliaMolSim/MolSim.git"))
Pkg.Registry.add(RegistrySpec(url = "https://github.com/ACEsuit/ACEregistry"))
'
shell: bash
- uses: julia-actions/julia-buildpkg@v1
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
using Pkg
Pkg.Registry.add("General")
Pkg.Registry.add(RegistrySpec(url = "https://github.com/cesmix-mit/CESMIX.git"))
Pkg.Registry.add(RegistrySpec(url = "https://github.com/JuliaMolSim/MolSim.git"))
Pkg.Registry.add(RegistrySpec(url = "https://github.com/ACEsuit/ACEregistry"))
'
shell: bash
- name: instantiate docs
Expand All @@ -34,9 +36,7 @@ jobs:
run: |
julia --project=docs -e '
using Documenter: DocMeta, doctest
using InteratomicPotentials
DocMeta.setdocmeta!(InteratomicPotentials, :DocTestSetup, :(using InteratomicPotentials); recursive=true)
doctest(InteratomicPotentials)
using DocumenterCitations
'
- name: generate docs
run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs docs/make.jl
Expand Down
11 changes: 8 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
name = "InteratomicPotentials"
uuid = "a9efe35a-c65d-452d-b8a8-82646cd5cb04"
authors = ["Dallas Foster <fostdall@mit.edu>"]
version = "0.2.6"
version = "0.2.7"

[deps]
ACE1 = "e3f9bc04-086e-409a-ba78-e9769fe067bb"
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
JuLIP = "945c410c-986d-556a-acb1-167a618e0462"
LAMMPS = "ee2e13b9-eee9-4449-aafa-cfa6a2dbe14d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

[compat]
AtomsBase = "0.2, 0.3"
AtomsBase = "0.3"
Distances = "0.10"
NearestNeighbors = "0.4.9"
StaticArrays = "1"
Unitful = "1"
UnitfulAtomic = "1"
julia = "1.6"
julia = "1.9"
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
[![Docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://cesmix-mit.github.io/InteratomicPotentials.jl/stable)
[![Docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://cesmix-mit.github.io/InteratomicPotentials.jl/dev)

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 data-driven and parameter-fitted 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 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 data-driven and parameter-fitted 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 also supports the Spectral Neighbor Analysis Potential (SNAP) potential of Thompson et al. 2015 (see documentation for bibliography) and a naive hacking of the Atomic Cluster Expansion of Drautz 2019 through the [ACE1.jl](https://github.com/ACEsuit/ACE1.jl/) julia package. We are working toward more complete implementation of these machine learning or data-driven potentials in the context of the CESMIX julia suite that seeks to fit and run these potentials for molecular dynamics. For additional details, see the [CESMIX](https://github.com/cesmix-mit) ecosystem.

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 part of the CESMIX molecular modeling suite. This package is also intended to be used with Atomistic.jl (for molecular dynamics, with Molly.jl), and PotentialLearning.jl (for fitting potentials from data).

This package is a work in progress.

Expand Down Expand Up @@ -68,7 +68,7 @@ set_parameters(lj, (ϵ = 2.0 * 1u"eV", σ = 1.0 * 1u"Å")) # Set parameters (re

## 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.
All interatomic potentials listed in this project are subtypes of `ArbitraryPotential`. There are three types of potentials currently implemented: `EmpiricalPotential`, `BasisPotential`, and combination potentials via `MixedPotentials`.

`EmpiricalPotential`s include two-body potentials like `BornMayer`, `LennardJones`. `MixedPotential` is a convenience type for allowing the linear combination of potentials. An example would be:
```julia
Expand All @@ -87,7 +87,6 @@ ZBL <: EmpiricalPotential

LinearCombinationPotential <: MixedPotential

# See InteratomicBasisPotentials.jl
BasisPotential <: AbstractPotential
SNAP <: BasisPotential
ACE <: BasisPotential
Expand Down
19 changes: 19 additions & 0 deletions benchmarks/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[deps]
ACE1 = "e3f9bc04-086e-409a-ba78-e9769fe067bb"
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
JuLIP = "945c410c-986d-556a-acb1-167a618e0462"
LAMMPS = "ee2e13b9-eee9-4449-aafa-cfa6a2dbe14d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
PProf = "e4faabce-9ead-11e9-39d9-4379958e3056"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

[compat]
julia = "1.9"
15 changes: 12 additions & 3 deletions benchmarks/lj_1000.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
include("helpers.jl")
push!(Base.LOAD_PATH, "../../")

using AtomsBase
using InteratomicPotentials
using LinearAlgebra
using Unitful
using UnitfulAtomic
using BenchmarkTools
using Plots
using BenchmarkTools

include("utils.jl")

T, = parse.(Int, ARGS)
T = parse.(Int, ARGS) # E.g. 10

potential = LennardJones(1.0u"eV", 1.0u"", 100.0u"", [:Ar])

system = load_configuration("benchmarks/data/lj_clusters/1000.xyz")
system = load_configuration("data/lj_clusters/1000.xyz")

display(@benchmark energy_and_force($system, $potential) seconds = T)
11 changes: 9 additions & 2 deletions benchmarks/profile.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
include("helpers.jl")
push!(Base.LOAD_PATH, "../../")

using AtomsBase
using InteratomicPotentials
using LinearAlgebra
using Unitful
using UnitfulAtomic
using BenchmarkTools
using PProf

@show N, NUM_ITER = parse.(Int, ARGS)
include("utils.jl")

@show N, NUM_ITER = parse.(Int, ARGS) # E.g. 100, 100

potential = LennardJones(1.0u"eV", 1.0u"", 100.0u"", [:Ar])

Expand Down
16 changes: 13 additions & 3 deletions benchmarks/scalability.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
include("helpers.jl")
push!(Base.LOAD_PATH, "../../")

using AtomsBase
using InteratomicPotentials
using LinearAlgebra
using Unitful
using UnitfulAtomic
using BenchmarkTools
using Plots

include("utils.jl")

potential = LennardJones(1.0u"eV", 1.0u"", 100.0u"", [:Ar])

ns = 250:250:10000
ns = 250:250:1000
@time times = map(ns) do N
system = generate_lj_cluster(N)
time = @belapsed energy_and_force($system, $potential)
Expand All @@ -15,6 +22,9 @@ end

@show times

p = plot(title="Scaling of energy_and_force on LJ Clusters", xlabel="Number of Atoms", ylabel="Median Time Elapsed (s)", legend=false)
p = plot(title="Scaling of energy_and_force on LJ Clusters",
xlabel="Number of Atoms",
ylabel="Median Time Elapsed (s)",
legend=false)
plot!(p, ns, times, markershape=:circle)
savefig(p, "scaling.svg")
6 changes: 0 additions & 6 deletions benchmarks/helpers.jl → benchmarks/utils.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
using AtomsBase
using InteratomicPotentials
using LinearAlgebra
using Unitful
using UnitfulAtomic

function load_configuration(filename::String)
box = [[8.0, 0.0, 0.0], [0.0, 8.0, 0.0], [0.0, 0.0, 8.0]] * 1u""
bcs = [DirichletZero(), DirichletZero(), DirichletZero()]
Expand Down
25 changes: 25 additions & 0 deletions docs/citation.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@article{Drautz2019,
title = {Atomic cluster expansion for accurate and transferable interatomic potentials},
author = {Drautz, Ralf},
journal = {Phys. Rev. B},
volume = {99},
issue = {1},
pages = {014104},
numpages = {15},
year = {2019},
month = {Jan},
publisher = {American Physical Society},
doi = {10.1103/PhysRevB.99.014104},
url = {https://link.aps.org/doi/10.1103/PhysRevB.99.014104}
}
@article{Thompson2015,
title = {Spectral neighbor analysis method for automated generation of quantum-accurate interatomic potentials},
journal = {Journal of Computational Physics},
volume = {285},
pages = {316-330},
year = {2015},
issn = {0021-9991},
doi = {https://doi.org/10.1016/j.jcp.2014.12.018},
url = {https://www.sciencedirect.com/science/article/pii/S0021999114008353},
author = {A.P. Thompson and L.P. Swiler and C.R. Trott and S.M. Foiles and G.J. Tucker},
}
64 changes: 41 additions & 23 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,65 @@ using Documenter
using DocumenterCitations
using Literate

DocMeta.setdocmeta!(InteratomicPotentials, :DocTestSetup, :(using InteratomicPotentials); recursive = true)
DocMeta.setdocmeta!(
InteratomicPotentials,
:DocTestSetup,
:(using InteratomicPotentials);
recursive = true,
)

bib = CitationBibliography(joinpath(@__DIR__, "citations.bib"))
bib = CitationBibliography(joinpath(@__DIR__, "citation.bib"))

# Generate examples

const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples")
const OUTPUT_DIR = joinpath(@__DIR__, "src/generated")

examples = Pair{String,String}[]
examples = [
"Lennard Jones Cluster" => "LJCluster/feature_exploration.jl"
]

for (_, name) in examples
example_filepath = joinpath(EXAMPLES_DIR, string(name, ".jl"))
Literate.markdown(example_filepath, OUTPUT_DIR, documenter = true)
for (_, example_path) in examples
s = split(example_path, "/")
sub_path, file_name = string(s[1:end-1]...), s[end]
example_filepath = joinpath(EXAMPLES_DIR, example_path)
Literate.markdown(example_filepath,
joinpath(OUTPUT_DIR, sub_path),
documenter = true)
end

examples = [title => joinpath("generated", string(name, ".md")) for (title, name) in examples]
examples = [title => joinpath("generated", replace(example_path, ".jl" => ".md"))
for (title, example_path) in examples]

makedocs(bib;
modules = [InteratomicPotentials],
authors = "CESMIX-MIT",
repo = "https://github.com/cesmix-mit/InteratomicPotentials.jl/blob/{commit}{path}#{line}",
sitename = "InteratomicPotentials.jl",
format = Documenter.HTML(;
prettyurls = get(ENV, "CI", "false") == "true",
canonical = "https://cesmix-mit.github.io/InteratomicPotentials.jl",
assets = String[],
),
pages = [
makedocs(
root = joinpath(dirname(pathof(InteratomicPotentials)), "..", "docs"),
source = "src",
build = "build",
clean = true,
doctest = true,
modules = [InteratomicPotentials],
repo = "https://github.com/cesmix-mit/InteratomicPotentials.jl/blob/{commit}{path}#{line}",
highlightsig = true,
sitename = "InteratomicPotentials.jl",
expandfirst = [],
draft = false,
pages = [
"Home" => "index.md",
"InteratomicPotentials Interface" => "interface.md",
"Examples" => examples,
"API Reference" => "api.md",
],
doctest = true,
linkcheck = true,
strict = true
"References" => "bibliography.md"
],
format = Documenter.HTML(;
prettyurls = get(ENV, "CI", "false") == "true",
canonical = "https://cesmix-mit.github.io/InteratomicPotentials.jl",
assets = String[],
),
plugins=[bib]
)

deploydocs(;
repo = "github.com/cesmix-mit/InteratomicPotentials.jl",
devbranch = "main",
push_preview = true
)
)
2 changes: 2 additions & 0 deletions docs/src/bibliography.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
```@bibliography
```
6 changes: 5 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# InteratomicPotentials

Package that provides a flexible suite for working with interatomic potentials. Defines an API for abstract interatomic potentials (currently supporting 2-body interactions) and the atomic configuration interface defined by AtomsBase.jl.
Package that provides a flexible suite for working with interatomic potentials. Defines an API for abstract interatomic potentials (currently supporting 2-body interactions) and the atomic configuration interface defined by AtomsBase.jl. This package also provides interatomic potentials that are defined using basis functions, in particular we support the Spectral Neighbor Analysis Potential (SNAP) (Thompson, 2015) and the Atomic Cluster Expansion (ACE) (Drautz, 2019). Defines an API for abstract interatomic potentials (currently supporting 2-body interactions) and the atomic configuration interface defined by AtomsBase.jl.

Developed as part of the CESMIX Julia package suite. See also ComposableWorkflows, InteratomicPotentials.jl, and PotentialLearning.jl.

Expand All @@ -15,3 +15,7 @@ The unit convention throughout the package and other packages in the CESMIX Juli
If you would like to use InteratomicPotentials in a molecular dynamics simulator, see [Atomistic.jl](https://github.com/cesmix-mit/Atomistic.jl). There, you will learn more about how the abstract classes provided in the present package can be used in conjuction with the Atomistic API and a variety of MD simulators.

If you would like to fit your potential parameters to data, see our project at [PotentialLearning.jl](https://github.com/cesmix-mit/PotentialLearning.jl), a work in progress, that aims to provide support for a variety of learning and inference tasks.

## References
Thompson, A.P., et al.: Spectral neighbor analysis method for automated generation of quantum-accurate interatomic potentials, Journal of Computational Physics, 285, 2015.
Drautz, R.: Atomic cluster expansion for accurate and transferable interatomic potentials. Phys. Rev. B Condens. Matter. 99, 014104 (2019).
14 changes: 13 additions & 1 deletion docs/src/interface.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# InteratomicPotentials Interface

# Instantiating a Built-In Interatomic Potentials
There are a number of built-in interatomic potentials that are available for users: Born-Mayer-Huggins, Lennard-Jones, Coulomb's Law, and Morse. These potentials are subtypes of `EmpiricalPotential`. There are additional basis potentials, the Spectral Neighbor Analysis Potential and Atomic Cluster Expansion, available in the related package `InteratomicBasisPotentials.jl`. In order to instantiate a potential, you need to provide the necessary potential parameters (see API documentation), radial cutoff, and species (i.e. elements) for which the potential is defined for.
There are a number of built-in interatomic potentials that are available for users: Born-Mayer-Huggins, Lennard-Jones, Coulomb's Law, and Morse. These potentials are subtypes of `EmpiricalPotential`. There are additional basis potentials, the Spectral Neighbor Analysis Potential and Atomic Cluster Expansion. In order to instantiate a potential, you need to provide the necessary potential parameters (see API documentation), radial cutoff, and species (i.e. elements) for which the potential is defined for.

Below is an example for the Lennard-Jones potential:
```julia
Expand All @@ -18,6 +18,18 @@ CustomPotential{T<:AbstractFloat} <: EmpiricalPotential{NamedTuple{(:a, :b, ...,
# where parameters are :a, :b, ..., :e
```

Below is an example for building an Atomic Cluster Expansion (ACE) potential:
```julia
body_order = 2
polynomial_degree = 8
r_inner_cutoff = 0.5 * u""
r_cutoff = 4.0 * u""
species = [:Ar, ]
wL = 1.0
csp = 1.0
ace_params = RPIParams(species, body_order, polynomial_degree, wL, csp, r_inner_cutoff, r_cutoff)
```

# Evaluating Interatomic Potentials
There are a number of signatures for evaluating the potential energy, force, and virial stress for the interatomic potentials. For most users it will be most convenient in order to define a configuration in terms of an `AtomsBase.jl` system (i.e., using a `FlexibleSystem`), which requires a list of atoms, boundary conditions, and box information. With such a system, evaluating the potential energy and force are straightforward:

Expand Down
6 changes: 0 additions & 6 deletions examples/LJCluster/Project.toml

This file was deleted.

Loading

0 comments on commit 973e0d5

Please sign in to comment.