Skip to content

Update of interface towards AtomsCalculator 0.2 #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.9'
- '1.10'
- 'nightly'
os:
- ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/Manifest.toml
/docs/Manifest.toml
/docs/build/
*~
.*.swp
33 changes: 16 additions & 17 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
name = "GeometryOptimization"
uuid = "673bf261-a53d-43b9-876f-d3c1fc8329c2"
authors = ["JuliaMolSim community"]
version = "0.0.1"
version = "0.0.2"

[deps]
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
AtomsCalculators = "a3e0e189-c65a-42c1-833c-339540406eb1"
EmpiricalPotentials = "38527215-9240-4c91-a638-d4250620c9e2"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"

[compat]
ASEconvert = "0.1"
AtomsBase = "0.3"
AtomsCalculators = "0.1"
DFTK = "0.6"
EmpiricalPotentials = "0.1.0"
Optimization = "3.20"
OptimizationOptimJL = "0.1"
StaticArrays = "1.8"
AtomsBuilder = "=0.0.4"
AtomsCalculators = "0.2"
DocStringExtensions = "0.9"
LineSearches = "7"
Optimization = "3"
OptimizationOptimJL = "0.3"
StaticArrays = "1"
TestItemRunner = "0.2"
Unitful = "1.19"
UnitfulAtomic = "1.0"
julia = "1.9"
Unitful = "1"
UnitfulAtomic = "1"
julia = "1.10"

[extras]
ASEconvert = "3da9722f-58c2-4165-81be-b4d7253e8fd2"
DFTK = "acf6eb54-70d9-11e9-0013-234b7a5f5337"
EmpiricalPotentials = "38527215-9240-4c91-a638-d4250620c9e2"
AtomsBuilder = "f5cc8831-eeb7-4288-8d9f-d6c1ddb77004"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"

[targets]
examples = ["DFTK", "ASEconvert", "EmpiricalPotentials"]
test = ["Test", "TestItemRunner"]
test = ["AtomsBuilder", "Test", "TestItemRunner"]
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaMolSim.github.io/GeometryOptimization.jl/stable/)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://JuliaMolSim.github.io/GeometryOptimization.jl/dev/)
[![Build Status](https://github.com/JuliaMolSim/GeometryOptimization.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaMolSim/GeometryOptimization.jl/actions/workflows/CI.yml?query=branch%3Amain)

A geometry optimization package for
[AtomsBase structures](https://github.com/JuliaMolSim/AtomsBase.jl)
and [AtomsCalculator calculators](https://github.com/JuliaMolSim/AtomsCalculators.jl).
See the [documentation](https://JuliaMolSim.github.io/GeometryOptimization.jl/stable/)
for examples and further details.
17 changes: 17 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
[deps]
ASEconvert = "3da9722f-58c2-4165-81be-b4d7253e8fd2"
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
AtomsBuilder = "f5cc8831-eeb7-4288-8d9f-d6c1ddb77004"
AtomsCalculators = "a3e0e189-c65a-42c1-833c-339540406eb1"
AtomsIO = "1692102d-eeb4-4df9-807b-c9517f998d44"
DFTK = "acf6eb54-70d9-11e9-0013-234b7a5f5337"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
EmpiricalPotentials = "38527215-9240-4c91-a638-d4250620c9e2"
GeometryOptimization = "673bf261-a53d-43b9-876f-d3c1fc8329c2"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OptimizationNLopt = "4e6fcdb7-1186-4e1f-a706-475e75c168bb"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"

[compat]
ASEconvert = "0.1"
DFTK = "0.6"
Documenter = "~1.5"
EmpiricalPotentials = "0.1"
14 changes: 14 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Setup julia dependencies for docs generation if not yet done
import Pkg
Pkg.activate(@__DIR__)
if !isfile(joinpath(@__DIR__, "Manifest.toml"))
Pkg.develop(Pkg.PackageSpec(path=joinpath(@__DIR__, "..")))
Pkg.instantiate()
end

using GeometryOptimization
using Documenter

Expand All @@ -16,6 +24,12 @@ makedocs(;
),
pages=[
"Home" => "index.md",
"Examples" => [
"examples/aluminium_dftk.md",
"examples/other_solvers.md",
"examples/tial_lj.md",
],
"apireference.md",
],
)

Expand Down
12 changes: 12 additions & 0 deletions docs/src/apireference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
```@meta
CurrentModule = GeometryOptimization
```

# API reference

```@index
```

```@autodocs
Modules = [GeometryOptimization]
```
81 changes: 81 additions & 0 deletions docs/src/examples/aluminium_dftk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Aluminium supercell using density-functional theory

In this example we will optimise the structure of a rattled
aluminium system using density-functional theory.

First we build a rattled aluminium system:

```@example dftk-aluminium
using AtomsBuilder
using Unitful

system = rattle!(bulk(:Al; cubic=true), 0.2u"Å")
```

Next we create a calculator employing the
[density-functional toolkit](https://dftk.org/)
to compute energies and forces at using the LDA density functional.
```@example dftk-aluminium
using DFTK

model_kwargs = (; functionals=[:lda_x, :lda_c_pw], temperature=1e-3)
basis_kwargs = (; kgrid=(3, 3, 3), Ecut=10.0)
scf_kwargs = (; tol=1e-6, mixing=KerkerMixing())
calc = DFTKCalculator(; model_kwargs, basis_kwargs, scf_kwargs, verbose=true)
nothing
```

We attach pseudopotentials to the aluminium system,
i.e. we tell DFTK, that each aluminium atom should be modelled using
a pseudopotential rather than the full Coulomb potential.

```@example dftk-aluminium
system = attach_psp(system; Al="hgh/lda/al-q3")
nothing
```

!!! info "Crude computational parameters"
Note, that these numerical parameters are chosen rather crudely in order
to give a fast runtime on CI systems. For production calculations one would
require larger computational parameters.

We perform the structure optimisation using the LBFGS solver
from Optim with solver parameters adapted for our geometry optimisation setting.
This is selected by passing the [GeometryOptimization.OptimLBFGS](@ref)
solver as the third argument.

```@example dftk-aluminium
using GeometryOptimization
GO = GeometryOptimization

results = minimize_energy!(system, calc, GO.OptimLBFGS();
tol_force=1e-4u"eV/Å",
show_trace=true)
nothing
```

The final energy is
```@example dftk-aluminium
results.energy
```

We can view the final structure
```@example dftk-aluminium
results.system
```

Some statistics about the optimisation
```@example dftk-aluminium
results.stats
```
or the details about the selected algorithm:
```@example dftk-aluminium
results.alg
```

The final state of the calculator object is also accessible
via `results.state` and could be employed for postprocessing
using the framework of the calculator. E.g. in the case
of `DFTK`, the `results.state` is what `DFTK` calls an `scfres`
and could just be used to plot a density of states or plot
bands or compute response properties.
58 changes: 58 additions & 0 deletions docs/src/examples/other_solvers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Using a different Optimization.jl compatible solver

In this example we perform the simplistic optimisation
the bond length of a Hydrogen molecule using a trust region
quasi-Newton method from
[NLopt](https://github.com/JuliaOpt/NLopt.jl).

We create a calculator employing the
[density-functional toolkit](https://dftk.org/)
to compute energies and forces at using the LDA density functional.

```@example other-solvers
using DFTK

model_kwargs = (; functionals=[:lda_x, :lda_c_pw])
basis_kwargs = (; kgrid=(1, 1, 1), Ecut=20.0)
scf_kwargs = (; tol=1e-6)
calc = DFTKCalculator(; model_kwargs, basis_kwargs, scf_kwargs, verbose=true)
nothing
```

and we build the hydrogen molecular system,
where we attach pseudopotential information for DFTK:

```@example other-solvers
using AtomsBuilder
using Unitful
using UnitfulAtomic

bounding_box = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]]u"Å"
system = periodic_system([:H => [0, 0, 1.]u"bohr",
:H => [0, 0, 3.]u"bohr"],
bounding_box)
system = attach_psp(system; H="hgh/lda/h-q1")
nothing
```

We now run [`GeometryOptimization.minimize_energy!`](@ref), but notably
pass the `NLopt.LD_TNEWTON` solver from `NLopt` as the
third argument to employ this solver. Extra keyword argument to `NLopt`
can be added, e.g. here the `maxevel=100`, which limits the solver to
100 function evaluations:
```@example other-solvers
using GeometryOptimization
using OptimizationNLopt
solver = NLopt.LD_TNEWTON()

results = minimize_energy!(system, calc, solver;
tol_force=1e-4u"eV/Å", maxeval=100)
nothing
```

The final hydrogen bond length is:

```@example other-solvers
using LinearAlgebra
norm(position(results.system[1]) - position(results.system[2]))
```
38 changes: 38 additions & 0 deletions docs/src/examples/tial_lj.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# TiAl structure optimisation

TODO Write some text motivating this example

Setup system:
```@example tial
using AtomsBase
using AtomsIO
using EmpiricalPotentials
using GeometryOptimization
GO = GeometryOptimization

system = load_system(joinpath(pkgdir(EmpiricalPotentials), "data/TiAl-1024.xyz"))
nothing
```

Setup calculator:
```@example tial
using Unitful
using UnitfulAtomic
calc = LennardJones(-1.0u"meV", 3.1u"Å", 13, 13, 6.0u"Å")
nothing
```

Minimise energy:
```julia
## TODO: Should run as @example once EmpiricalPotentials is compatible

results = minimize_energy!(system, calc, GO.OptimCG(); maxiters=10, show_trace=true)
results.energy
```

Final structure:
```julia
## TODO: Should run as @example once EmpiricalPotentials is compatible

results.system
```
43 changes: 38 additions & 5 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,44 @@ CurrentModule = GeometryOptimization

# GeometryOptimization

Documentation for [GeometryOptimization](https://github.com/ortner/GeometryOptimization.jl).
A geometry optimization package for
[AtomsBase structures](https://github.com/JuliaMolSim/AtomsBase.jl)
and [AtomsCalculator calculators](https://github.com/JuliaMolSim/AtomsCalculators.jl).
The source code can be found [on github](https://github.com/JuliaMolSim/GeometryOptimization.jl).

```@index
```
## Motivating example

We consider the optimisation of the bondlength of a hydrogen
molecule using a simple Lennard Jones potential:

```julia
## TODO: Should run as @example once EmpiricalPotentials is compatible
using AtomsBase
using EmpiricalPotentials
using GeometryOptimization
using Unitful
using UnitfulAtomic

# Setup system and calculator
system = isolated_system([:H => [0, 0, 0.0]u"bohr",
:H => [0, 0, 1.9]u"bohr"])
calc = LennardJones(-1.17u"hartree", 0.743u"angstrom", 1, 1, 0.6u"nm")

```@autodocs
Modules = [GeometryOptimization]
# Run the geometry optimisation
results = minimize_energy!(system, calc)

# Inspect the results
optimised_system = results.system
optimised_bondlength = norm(position(optsystem[1]) - position(optsystem[2]))
```

The idea is that
any [AtomsBase](https://github.com/JuliaMolSim/AtomsBase.jl)-compatible
structure can be employed as a `system`
any [AtomsCalculators](https://github.com/JuliaMolSim/AtomsCalculators.jl)-compatible
calculator as a `calc`. See the list of examples to get an overview of possible
calculators to employ.

Note that [`minimize_energy!`](@ref) supports further arguments to fine-tune the
convergence tolerance or customise the solver selection.
See the API documentation or the examples to explore this.
Loading
Loading