diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6d8fd48..2c9374c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -72,6 +72,6 @@ jobs: shell: julia --project=docs --color=yes {0} run: | using Documenter: DocMeta, doctest - using PseudoLibraries - DocMeta.setdocmeta!(PseudoLibraries, :DocTestSetup, :(using PseudoLibraries); recursive=true) - doctest(PseudoLibraries) + using PseudoPotentialData + DocMeta.setdocmeta!(PseudoPotentialData, :DocTestSetup, :(using PseudoPotentialData); recursive=true) + doctest(PseudoPotentialData) diff --git a/Project.toml b/Project.toml index fe60dfb..b64f5fb 100644 --- a/Project.toml +++ b/Project.toml @@ -1,4 +1,4 @@ -name = "PseudoLibraries" +name = "PseudoPotentialData" uuid = "5751a51d-ac76-4487-a056-413ecf6fbe19" authors = ["Michael F. Herbst and contributors"] version = "0.1.0" diff --git a/README.md b/README.md index d01525e..81aa317 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,35 @@ -# PseudoLibraries +# PseudoPotentialData -[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliamolsim.github.io/PseudoLibraries.jl/stable/) -[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliamolsim.github.io/PseudoLibraries.jl/dev/) -[![Build Status](https://github.com/JuliaMolSim/PseudoLibraries.jl/actions/workflows/CI.yml/badge.svg?branch=master)](https://github.com/JuliaMolSim/PseudoLibraries.jl/actions/workflows/CI.yml?query=branch%3Amaster) -[![Coverage](https://codecov.io/gh/JuliaMolSim/PseudoLibraries.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMolSim/PseudoLibraries.jl) +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliamolsim.github.io/PseudoPotentialData.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliamolsim.github.io/PseudoPotentialData.jl/dev/) +[![Build Status](https://github.com/JuliaMolSim/PseudoPotentialData.jl/actions/workflows/CI.yml/badge.svg?branch=master)](https://github.com/JuliaMolSim/PseudoPotentialData.jl/actions/workflows/CI.yml?query=branch%3Amaster) +[![Coverage](https://codecov.io/gh/JuliaMolSim/PseudoPotentialData.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMolSim/PseudoPotentialData.jl) Package providing programmatic access -to standard pseudopotentials in solid-state calculations. -In using this library the combination of a string identifier and the element +to standard pseudopotential data files for solid-state calculations. +The combination of a string identifier for the +pseudopotential family and the element symbol provides a unique and reproducible mapping to a pseudopotential file. -Moreover in case the pseudopotential file -happens to be missing on the computer Julia's artifact system takes -care to automatically download it as needed. +In case the pseudopotential data file happens to be missing on the computer +it will be automatically download as needed. For example, the following code automatically downloads the pseudopotential -file of the [stringent pseudodojo](http://www.pseudo-dojo.org/) pseudopotential -for LDA pseudopotentials (referred to by the identifier `pd_nc_sr_lda_stringent_0.4.1_upf`) -and places the full path to the downloaded pseudopotential file into the `filename` variable: +file for silicon of the [stringent pseudodojo](http://www.pseudo-dojo.org/) +family for LDA pseudopotentials +(referred to by the identifier `pd_nc_sr_lda_stringent_0.4.1_upf`) +and places the full path to the downloaded pseudopotential file +into the `filename` variable: ```julia -using PseudoLibraries +using PseudoPotentialData identifier = "pd_nc_sr_lda_stringent_0.4.1_upf" -library = PseudoLibrary(identifier) -filename = pseudofile(library, :Si) +family = PseudoFamily(identifier) +filename = pseudofile(family, :Si) ``` For a list of available identifiers see ```julia -PseudoLibraries.available_identifiers() +PseudoPotentialData.family_identifiers() ``` More details on the meaning of these keys is given in the README of the diff --git a/docs/Project.toml b/docs/Project.toml index d809be0..cb9517a 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,3 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -PseudoLibraries = "5751a51d-ac76-4487-a056-413ecf6fbe19" +PseudoPotentialData = "5751a51d-ac76-4487-a056-413ecf6fbe19" diff --git a/docs/make.jl b/docs/make.jl index e6cb9d0..7c0db86 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,14 +1,14 @@ -using PseudoLibraries +using PseudoPotentialData using Documenter -DocMeta.setdocmeta!(PseudoLibraries, :DocTestSetup, :(using PseudoLibraries); recursive=true) +DocMeta.setdocmeta!(PseudoPotentialData, :DocTestSetup, :(using PseudoPotentialData); recursive=true) makedocs(; - modules=[PseudoLibraries], + modules=[PseudoPotentialData], authors="Michael F. Herbst and contributors", - sitename="PseudoLibraries.jl", + sitename="PseudoPotentialData.jl", format=Documenter.HTML(; - canonical="https://juliamolsim.github.io/PseudoLibraries.jl", + canonical="https://juliamolsim.github.io/PseudoPotentialData.jl", edit_link="master", assets=String[], ), @@ -18,6 +18,6 @@ makedocs(; ) deploydocs(; - repo="github.com/JuliaMolSim/PseudoLibraries.jl", + repo="github.com/JuliaMolSim/PseudoPotentialData.jl", devbranch="master", ) diff --git a/docs/src/index.md b/docs/src/index.md index 050665b..749d0b7 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,11 +1,11 @@ ```@meta -CurrentModule = PseudoLibraries +CurrentModule = PseudoPotentialData ``` -# PseudoLibraries +# PseudoPotentialData Enables programmatic access to -standard pseudopotential libraries in solid-state calculations. +standard pseudopotential libraries for solid-state calculations. In using this library the combination of a string identifier and the element symbol provides a unique and reproducible mapping to a pseudopotential file. Moreover in case the pseudopotential file @@ -20,10 +20,10 @@ for LDA pseudopotentials (referred to by the identifier `pd_nc_sr_lda_stringent_ and places the full path to the downloaded pseudopotential file into the `filename` variable: ```@example index-example -using PseudoLibraries +using PseudoPotentialData identifier = "pd_nc_sr_lda_stringent_0.4.1_upf" -library = PseudoLibrary(identifier) -filename = library[:Si] +family = PseudoFamily(identifier) +filename = pseudofile(family, :Si) ``` As you see this will be a string such as `/home/user/.julia/artifacts/56094b8162385233890d523c827ba06e07566079/Si.upf`, @@ -34,26 +34,21 @@ It is therefore highly recommended to use the above mechanism based on `identfier` and element symbol instead of hard-coding the expanded path in user scripts. -An alternative version to achieve the same thing as above is +For multiple elements you can similarly use ```@example index-example -filename = pseudofile(library, :Si) -``` -or for multiple elements: -```@example index-example -pseudofile.(library, [:C, :Si]) +pseudofile.(family, [:C, :Si]) ``` -Some metadata information is stored in the `library` object: +Some metadata information is stored in the `family` object: ```@example index-example -library +family ``` For a list of available identifiers see ```@example index-example -PseudoLibraries.available_identifiers() +PseudoPotentialData.family_identifiers() ``` -More details on the meaning of these keys is given -in the README of thei +More details on the meaning of these keys is given in the README of the [PseudoLibrary](https://github.com/JuliaMolSim/PseudoLibrary/blob/7c4b71a3b9d70a229d757aa6d546ef22b83a85a9/README.md) repository. @@ -64,5 +59,5 @@ repository. ## Interface ```@autodocs -Modules = [PseudoLibraries] +Modules = [PseudoPotentialData] ``` diff --git a/src/PseudoLibraries.jl b/src/PseudoLibraries.jl deleted file mode 100644 index 0df2202..0000000 --- a/src/PseudoLibraries.jl +++ /dev/null @@ -1,67 +0,0 @@ -module PseudoLibraries -using Artifacts -using Compat: @compat -using LazyArtifacts -using TOML - -export PseudoLibrary, pseudofile -@compat public available_identifiers - -struct PseudoLibrary - identifier::String - # metadata - extension::String # Filename expected as $(symbol).$(extension) - functional::String # Functional keyword (or "" if unspecified) - version::VersionNumber - # TODO More things will probably follow - # - Referencse to papers describing these pseudopotentials - # - Elements available -end - -""" -Construction of a PseudoLibrary from a `identifier` representing -the pseudopotential library to use. -""" -function PseudoLibrary(identifier::AbstractString) - artifact_file = find_artifacts_toml(@__FILE__) - @assert !isnothing(artifact_file) - meta = artifact_meta(identifier, artifact_file) - isnothing(meta) && throw(ArgumentError("Invalid pseudo identifier: $identifier")) - PseudoLibrary(identifier, - meta["extension"], - meta["functional"], - VersionNumber(meta["version"])) -end - -Base.Broadcast.broadcastable(l::PseudoLibrary) = Ref(l) - - -"""Get the list of available pseudopotential library keys.""" -function available_identifiers() - artifact_file = find_artifacts_toml(@__FILE__) - @assert !isnothing(artifact_file) - collect(keys(TOML.parsefile(artifact_file))) -end - - -""" -Return the directory containing the pseudo files. -This downloads the artifact if necessary. -""" -artifact_directory(library::PseudoLibrary) = (@artifact_str "$(library.identifier)") - -""" -Get the full path to the file containing the pseudopotential information -for a particular element and a particular pseudopotential library. -""" -function pseudofile(library::PseudoLibrary, element::Symbol) - file = joinpath(artifact_directory(library), "$(element)." * library.extension) - isfile(file) || throw(KeyError(element)) - file -end -function pseudofile(identifier::AbstractString, element::Symbol) - pseudofile(PseudoLibrary(identifier), element) -end -Base.getindex(library::PseudoLibrary, element) = pseudofile(library, element) - -end diff --git a/src/PseudoPotentialData.jl b/src/PseudoPotentialData.jl new file mode 100644 index 0000000..97b72be --- /dev/null +++ b/src/PseudoPotentialData.jl @@ -0,0 +1,72 @@ +module PseudoPotentialData +using Artifacts +using Compat: @compat +using LazyArtifacts +using TOML + +export PseudoFamily, pseudofile +@compat public families +@compat public family_identifiers + +struct PseudoFamily + identifier::String + # metadata + extension::String # Filename expected as $(symbol).$(extension) + functional::String # DFT functional keyword (or "" if unspecified) + version::VersionNumber + # TODO More things will probably follow + # - Type of pseudisation (norm-conserving, PAW, ...) + # - References to papers describing these pseudopotentials + # - Elements available +end + +""" +Construction of a PseudoFamily from a `identifier` representing +the pseudopotential family to use. +""" +function PseudoFamily(identifier::AbstractString) + artifact_file = find_artifacts_toml(@__FILE__) + @assert !isnothing(artifact_file) + meta = artifact_meta(identifier, artifact_file) + isnothing(meta) && throw(ArgumentError("Invalid pseudo identifier: $identifier")) + PseudoFamily(identifier, + meta["extension"], + meta["functional"], + VersionNumber(meta["version"])) +end + +Base.Broadcast.broadcastable(l::PseudoFamily) = Ref(l) + + +"""Get the list of available pseudopotential family identifiers.""" +function family_identifiers() + artifact_file = find_artifacts_toml(@__FILE__) + @assert !isnothing(artifact_file) + collect(keys(TOML.parsefile(artifact_file))) +end + +"""The list of all known pseudopotential families.""" +const families = map(PseudoFamily, family_identifiers()) + + +""" +Return the directory containing the pseudo files. +This downloads the artifact if necessary. +""" +artifact_directory(family::PseudoFamily) = (@artifact_str "$(family.identifier)") + +""" +Get the full path to the file containing the pseudopotential information +for a particular element and a particular pseudopotential `family`. +The family can be specified as an identifier or an object. +""" +function pseudofile(family::PseudoFamily, element::Symbol) + file = joinpath(artifact_directory(family), "$(element)." * family.extension) + isfile(file) || throw(KeyError(element)) + file +end +function pseudofile(family::AbstractString, element::Symbol) + pseudofile(PseudoFamily(family), element) +end + +end diff --git a/test/runtests.jl b/test/runtests.jl index 83cee1e..acee2e1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,32 +1,30 @@ -using PseudoLibraries +using PseudoPotentialData using Test -@testset "PseudoLibraries.jl" begin - @testset "Test one library can be loaded" begin +@testset "PseudoPotentialData.jl" begin + @testset "Test one family can be loaded" begin identifier = "pd_nc_sr_lda_stringent_0.4.1_upf" - library = PseudoLibrary(identifier) - @test library.identifier == identifier - @test library.extension == "upf" - @test library.functional == "lda" - @test library.version == v"0.4.1" + family = PseudoFamily(identifier) + @test family.identifier == identifier + @test family.extension == "upf" + @test family.functional == "lda" + @test family.version == v"0.4.1" file = pseudofile("pd_nc_sr_lda_stringent_0.4.1_upf", :Si) @test basename(file) == "Si.upf" - @test file == pseudofile(library, :Si) - @test file == library[:Si] + @test file == pseudofile(family, :Si) - files = pseudofile.(library, [:Si, :Si]) + files = pseudofile.(family, [:Si, :Si]) @test all(isequal(file), files) - @test_throws KeyError library[:Uun] - @test_throws KeyError pseudofile(library, :Uun) - @test_throws KeyError pseudofile(library, :Uun) + @test_throws KeyError pseudofile(family, :Uun) + @test_throws KeyError pseudofile(identifier, :Uub) end @testset "Test all libraries can be loaded" begin - for identifier in PseudoLibraries.available_identifiers() - library = PseudoLibrary(identifier) - @test library.identifier == identifier + for identifier in PseudoPotentialData.family_identifiers() + family = PseudoFamily(identifier) + @test family.identifier == identifier end end end