diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d60afd16..9b00d9ea 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,24 +19,25 @@ concurrency: cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.julia-arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} strategy: - fail-fast: false matrix: - version: - - '1.10' - os: - - ubuntu-latest - arch: - - x64 + julia-version: ['lts', '1', 'nightly'] + julia-arch: [x64] + os: [ubuntu-latest] + include: + - julia-version: '1' + os: macos-latest + julia-arch: aarch64 + fail-fast: false steps: - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v1 + - uses: julia-actions/setup-julia@v2 with: - version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/cache@v1 + version: ${{ matrix.julia-version }} + arch: ${{ matrix.julia-arch }} + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 @@ -45,6 +46,7 @@ jobs: files: lcov.info token: ${{ secrets.COVERALLS_REPO_TOKEN }} fail_ci_if_error: false + if: ${{ matrix.julia-version == '1' }} - uses: julia-actions/julia-uploadcoveralls@v1 env: COVERALLS_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 3dfba52e..a4ebaf94 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -37,7 +37,7 @@ jobs: - name: "Run CompatHelper" run: | import CompatHelper - CompatHelper.main() + CompatHelper.main(; master_branch="dev") shell: julia --color=yes {0} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index 2bacdb87..be5f85c6 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,12 +1,9 @@ name: TagBot on: - issue_comment: + issue_comment: # THIS BIT IS NEW types: - created workflow_dispatch: - inputs: - lookback: - default: 3 permissions: actions: read checks: read @@ -22,10 +19,12 @@ permissions: statuses: read jobs: TagBot: + # THIS 'if' LINE IS NEW if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + # NOTHING BELOW HAS CHANGED runs-on: ubuntu-latest steps: - uses: JuliaRegistries/TagBot@v1 with: token: ${{ secrets.GITHUB_TOKEN }} - ssh: ${{ secrets.DOCUMENTER_KEY }} + ssh: ${{ secrets.DOCUMENTER_KEY }} \ No newline at end of file diff --git a/README.md b/README.md index dafa1cd6..238b0023 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # FreeBird [![Build Status](https://github.com/wexlergroup/FreeBird.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/wexlergroup/FreeBird.jl/actions/workflows/CI.yml?query=branch%3Amain) -[![Coverage Status](https://coveralls.io/repos/github/wexlergroup/FreeBird.jl/badge.svg?branch=feature/simple-lennard-jones)](https://coveralls.io/github/wexlergroup/FreeBird.jl?branch=feature/simple-lennard-jones) +[![Coverage Status](https://coveralls.io/repos/github/wexlergroup/FreeBird.jl/badge.svg?branch=main)](https://coveralls.io/github/wexlergroup/FreeBird.jl?branch=main) [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://wexlergroup.github.io/FreeBird.jl/dev/) +[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/JuliaDiff/BlueStyle) *Free energy calculators by Bayesian-inspired nested sampling and other integration techniques* @@ -15,6 +16,11 @@ Once Julia is installed, you can install the `FreeBird` package from the Julia R ```julia-repl julia> ] # press the "]" key on your keyboard to enter the Pkg manager +pkg> add FreeBird +``` +Or, if you want to install a specific branch from GitHub, you can do so with: + +```julia-repl pkg> add https://github.com/wexlergroup/FreeBird.jl#branch_name ``` To get back to the Julia REPL, press `Ctrl+C` or backspace (when the REPL cursor is at the beginning of the input). diff --git a/docs/make.jl b/docs/make.jl index 2536b0a7..fa9cf8b0 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -9,8 +9,8 @@ makedocs(; "AbstractLiveSets" => "AbstractLiveSets.md", "AbstractWalkers" => "AbstractWalkers.md", "SamplingSchemes" => "SamplingSchemes.md", - "Potentials" => "AbstractPotentials.md", - "Hamiltonians" => "AbstractHamiltonians.md", + "AbstractPotentials" => "AbstractPotentials.md", + "AbstractHamiltonians" => "AbstractHamiltonians.md", "EnergyEval" => "EnergyEval.md", "MonteCarloMoves" => "MonteCarloMoves.md", "FreeBirdIO" => "FreeBirdIO.md", @@ -31,6 +31,6 @@ deploydocs( repo = "github.com/wexlergroup/FreeBird.jl.git", target = "build", branch = "gh-pages", - devbranch = "dev", + # devbranch = "dev", push_preview = true, ) diff --git a/docs/src/quick_start.md b/docs/src/quick_start.md index cc1ee787..1994c10f 100644 --- a/docs/src/quick_start.md +++ b/docs/src/quick_start.md @@ -2,9 +2,18 @@ EditURL = "../../scripts/quick_start.jl" ``` +# Quick start guide to FreeBird.jl + This is a quick start guide to using the FreeBird.jl package. +It covers the basic functionalities of the package, such as +generating atomistic and lattice walkers, defining a potential energy function or +Hamiltonian, and running a sampling simulation. +For more detailed information, please refer to the documentation of the package. +You can find the runnable version of this script in the `scripts` directory of the package. + +## Atomistic walkers and nested sampling -Load the FreeBird.jl package: +First, let's load the FreeBird.jl package: ````@example quick_start using FreeBird @@ -71,9 +80,9 @@ The `lj` potential will be used to attached and used to calculate the potential ls = LJAtomWalkers(walkers, lj) ```` -Here, `ls` is a [`LJAtomWalkers`](@ref) type, and has the `walkers` and `lj` files attached to it. +Here, `ls` is a [`LJAtomWalkers`](@ref) type, and has the `walkers` and `lj` fields attached to it. -Now, time to set up a simulation. We will be using nested sampling, a Bayesian inference method, as an example here. +Now, time to set up a simulation. We will be using nested sampling, a Bayesian-inference inspired method, as an example here. First, we need to define the nested sampling parameters: ````@example quick_start @@ -125,10 +134,89 @@ They should be in a more ordered state, in this case, a cluster, than the initia That's it! You have successfully run a nested sampling simulation using the FreeBird.jl package. -For more information, please refer to the documentation of the FreeBird.jl package. +## Lattice walkers and exact enumeration + +Another feature of FreeBird.jl is the ability to work with lattice systems. +The lattice systems are defined by the [`MLattice`](@ref) which is a parametrized type. +```julia +MLattice{C,G}( + lattice_vectors::Matrix{Float64}, + basis::Vector{Tuple{Float64, Float64, Float64}}, + supercell_dimensions::Tuple{Int64, Int64, Int64}, + periodicity::Tuple{Bool, Bool, Bool}, + components::Vector{Vector{Bool}}, + adsorptions::Vector{Bool}, + cutoff_radii::Vector{Float64}, +) where {C,G} +``` +The `C` parameter is the number of components in the system, and the `G` parameter defines the geometry of the lattice. + +Now, let's create a simple square lattice system with single component: + +````@example quick_start +ml = MLattice{1,SquareLattice}(components=[[1,2]]) +```` + +When you run the above code, the outer constructor of `MLattice` will be called. +Many of the arguments are optional and have default values. +The `components` argument is a vector of vectors that defines the components of the system. +The `components=[[1,2]]` argument specifies that the system has a single component, +and the first and second sites are occupied. +```julia +MLattice{C,SquareLattice}(; lattice_constant::Float64=1.0, + basis::Vector{Tuple{Float64,Float64,Float64}}=[(0.0, 0.0, 0.0)], + supercell_dimensions::Tuple{Int64,Int64,Int64}=(4, 4, 1), + periodicity::Tuple{Bool,Bool,Bool}=(true, true, false), + cutoff_radii::Vector{Float64}=[1.1, 1.5], + components::Union{Vector{Vector{Int64}},Vector{Vector{Bool}},Symbol}=:equal, + adsorptions::Union{Vector{Int},Symbol}=:full) +``` + +You may notice that the above code returns a `SLattice` type. +The `SLattice` type is simply an alias for the `MLattice{1,G}`, +where `G` is the geometry of the lattice and the number of components is fixed to 1. +You can also directly call the `SLattice`, it will give the same result: + +````@example quick_start +sl = SLattice{SquareLattice}(components=[[1,2]]) +```` + +Now, let's define a Hamiltonian for the lattice system: + +````@example quick_start +ham = GenericLatticeHamiltonian(-0.04, [-0.01, -0.0025], u"eV") +```` + +The [`GenericLatticeHamiltonian`](@ref) type is a struct that holds the parameters of the Hamiltonian. +The first argument is the on-site energy, and the second argument is the list of n-th nearest-neighbors energy. +The third argument is the unit of the energy. + +To run exact enumeration, we only need a initial walker/lattice configuration, and +the Hamiltonian. Let's run the exact enumeration: + +````@example quick_start +df, ls = exact_enumeration(sl, ham) +```` + +The results of the exact enumeration are stored in the `df` and `ls` variables. +The `df` variable is a `DataFrame` that contains the list of energies, as well as the configurations. +The `ls` variable is the final liveset that contains all possible configurations of the lattice system. +Let's see how the first configuration looks like: + +````@example quick_start +ls.walkers[1].configuration +```` + +It's the initial configuration of the lattice system. +Let's see how the last configuration looks like: + +````@example quick_start +ls.walkers[end].configuration +```` + +Be warned that the exact enumeration can be computationally expensive for large systems. -Please see other scripts in the `scripts` directory for more examples and use cases. -More tutorials and examples will be added in the future. Stay tuned! +That's it! You have successfully run an exact enumeration simulation using the FreeBird.jl package. --- diff --git a/scripts/quick_start.jl b/scripts/quick_start.jl index b573cd8e..0c22cf15 100644 --- a/scripts/quick_start.jl +++ b/scripts/quick_start.jl @@ -1,6 +1,15 @@ +# # Quick start guide to FreeBird.jl + # This is a quick start guide to using the FreeBird.jl package. +# It covers the basic functionalities of the package, such as +# generating atomistic and lattice walkers, defining a potential energy function or +# Hamiltonian, and running a sampling simulation. +# For more detailed information, please refer to the documentation of the package. +# You can find the runnable version of this script in the `scripts` directory of the package. + +# ## Atomistic walkers and nested sampling -# Load the FreeBird.jl package: +# First, let's load the FreeBird.jl package: using FreeBird # Now, let's create a few configurations of a simple atomistic system with six particles in a 3D box. @@ -42,9 +51,9 @@ lj = LJParameters(epsilon=0.1, sigma=2.5, cutoff=4.0) # We now can create a so-called *liveset* that will be used to store the walkers during the simulation. # The `lj` potential will be used to attached and used to calculate the potential energy of the walkers. ls = LJAtomWalkers(walkers, lj) -# Here, `ls` is a [`LJAtomWalkers`](@ref) type, and has the `walkers` and `lj` files attached to it. +# Here, `ls` is a [`LJAtomWalkers`](@ref) type, and has the `walkers` and `lj` fields attached to it. -# Now, time to set up a simulation. We will be using nested sampling, a Bayesian inference method, as an example here. +# Now, time to set up a simulation. We will be using nested sampling, a Bayesian-inference inspired method, as an example here. # First, we need to define the nested sampling parameters: ns_params = NestedSamplingParameters(200, 0.1, 0.01, 1e-5, 1.0, 0, 200) @@ -77,7 +86,70 @@ liveset.walkers[1].configuration # That's it! You have successfully run a nested sampling simulation using the FreeBird.jl package. -# For more information, please refer to the documentation of the FreeBird.jl package. - -# Please see other scripts in the `scripts` directory for more examples and use cases. -# More tutorials and examples will be added in the future. Stay tuned! \ No newline at end of file +# ## Lattice walkers and exact enumeration + +# Another feature of FreeBird.jl is the ability to work with lattice systems. +# The lattice systems are defined by the [`MLattice`](@ref) which is a parametrized type. +#===================== +```julia +MLattice{C,G}( + lattice_vectors::Matrix{Float64}, + basis::Vector{Tuple{Float64, Float64, Float64}}, + supercell_dimensions::Tuple{Int64, Int64, Int64}, + periodicity::Tuple{Bool, Bool, Bool}, + components::Vector{Vector{Bool}}, + adsorptions::Vector{Bool}, + cutoff_radii::Vector{Float64}, +) where {C,G} +``` +=====================# +# The `C` parameter is the number of components in the system, and the `G` parameter defines the geometry of the lattice. + +# Now, let's create a simple square lattice system with single component: +ml = MLattice{1,SquareLattice}(components=[[1,2]]) + +#== +When you run the above code, the outer constructor of `MLattice` will be called. +Many of the arguments are optional and have default values. +The `components` argument is a vector of vectors that defines the components of the system. +The `components=[[1,2]]` argument specifies that the system has a single component, +and the first and second sites are occupied. +```julia +MLattice{C,SquareLattice}(; lattice_constant::Float64=1.0, + basis::Vector{Tuple{Float64,Float64,Float64}}=[(0.0, 0.0, 0.0)], + supercell_dimensions::Tuple{Int64,Int64,Int64}=(4, 4, 1), + periodicity::Tuple{Bool,Bool,Bool}=(true, true, false), + cutoff_radii::Vector{Float64}=[1.1, 1.5], + components::Union{Vector{Vector{Int64}},Vector{Vector{Bool}},Symbol}=:equal, + adsorptions::Union{Vector{Int},Symbol}=:full) +``` +==# + +# You may notice that the above code returns a `SLattice` type. +# The `SLattice` type is simply an alias for the `MLattice{1,G}`, +# where `G` is the geometry of the lattice and the number of components is fixed to 1. +# You can also directly call the `SLattice`, it will give the same result: +sl = SLattice{SquareLattice}(components=[[1,2]]) + +# Now, let's define a Hamiltonian for the lattice system: +ham = GenericLatticeHamiltonian(-0.04, [-0.01, -0.0025], u"eV") +# The [`GenericLatticeHamiltonian`](@ref) type is a struct that holds the parameters of the Hamiltonian. +# The first argument is the on-site energy, and the second argument is the list of n-th nearest-neighbors energy. +# The third argument is the unit of the energy. + +# To run exact enumeration, we only need a initial walker/lattice configuration, and +# the Hamiltonian. Let's run the exact enumeration: +df, ls = exact_enumeration(sl, ham) + +# The results of the exact enumeration are stored in the `df` and `ls` variables. +# The `df` variable is a `DataFrame` that contains the list of energies, as well as the configurations. +# The `ls` variable is the final liveset that contains all possible configurations of the lattice system. +# Let's see how the first configuration looks like: +ls.walkers[1].configuration +# It's the initial configuration of the lattice system. +# Let's see how the last configuration looks like: +ls.walkers[end].configuration + +# Be warned that the exact enumeration can be computationally expensive for large systems. + +# That's it! You have successfully run an exact enumeration simulation using the FreeBird.jl package. \ No newline at end of file