diff --git a/REQUIRE b/REQUIRE index 227124e..5bb39fd 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,6 +1,5 @@ julia 0.5 BinDeps -NamedTuples Documenter DocStringExtensions Unitful diff --git a/docs/src/index.md b/docs/src/index.md index e631ab7..3d7118a 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -42,7 +42,7 @@ The functionals can be queried for their [`kind`](@ref), [`family`](@ref), ## A word about input dimensionality The functionals expect input arrays ρ and σ=|∇ρ|, and (optionally) a number of output -arrays, for the energy `εxc`, and the different derivatives, e.g. ∂εxc/∂ρ. Because we are +arrays, for the energy `ϵ`, and the different derivatives, e.g. ∂ϵ/∂ρ. Because we are accessing a C library, some care must be taken when creating these arrays. * All arrays must be dense (contiguous in memory) and the element type must match `Cdouble` @@ -51,28 +51,28 @@ accessing a C library, some care must be taken when creating these arrays. * spin-polarized cases: the **first** dimension of ρ must be 2: `size(ρ) = (2, ....)`. Other arrays must match in very specific ways: - |LDA | unpolarized | polarized | - |------------|-------------|---------------------------| - |ρ | any | `(2, ...)` | - |εxc | `size(ρ)` | `size(ρ)[2:end]` | - |∂εxc/∂ρ | `size(ρ)` | `size(ρ)` | - |∂²εxc/∂ρ² | `size(ρ)` | `(3, size(ρ)[2:end]...)` | - |∂³εxc/∂ρ³ | `size(ρ)` | `(4, size(ρ)[2:end]...)` | - - |GGA | unpolarized | polarized | - |------------|-------------|---------------------------| - |ρ | any | `(2, ...)` | - |σ | `size(ρ)` | `(3, size(ρ)[2:end]...)` | - |εxc | `size(ρ)` | `size(ρ)[2:end]` | - |∂εxc/∂ρ | `size(ρ)` | `size(ρ)` | - |∂εxc/∂σ | `size(ρ)` | `(3, size(ρ)[2:end]...)` | - |∂²εxc/∂ρ² | `size(ρ)` | `(3, size(ρ)[2:end]...)` | - |∂²εxc/∂ρ∂σ | `size(ρ)` | `(6, size(ρ)[2:end]...)` | - |∂²εxc/∂σ² | `size(ρ)` | `(6, size(ρ)[2:end]...)` | - |∂³εxc/∂ρ³ | `size(ρ)` | `(4, size(ρ)[2:end]...)` | - |∂³εxc/∂ρ²∂σ | `size(ρ)` | `(9, size(ρ)[2:end]...)` | - |∂³εxc/∂ρ∂σ² | `size(ρ)` | `(10, size(ρ)[2:end]...)` | - |∂³εxc/∂σ³ | `size(ρ)` | `(12, size(ρ)[2:end]...)` | + |LDA | unpolarized | polarized | + |----------|-------------|---------------------------| + |ρ | any | `(2, ...)` | + |ϵ | `size(ρ)` | `size(ρ)[2:end]` | + |∂ϵ/∂ρ | `size(ρ)` | `size(ρ)` | + |∂²ϵ/∂ρ² | `size(ρ)` | `(3, size(ρ)[2:end]...)` | + |∂³ϵ/∂ρ³ | `size(ρ)` | `(4, size(ρ)[2:end]...)` | + + |GGA | unpolarized | polarized | + |----------|-------------|---------------------------| + |ρ | any | `(2, ...)` | + |σ | `size(ρ)` | `(3, size(ρ)[2:end]...)` | + |ϵ | `size(ρ)` | `size(ρ)[2:end]` | + |∂ϵ/∂ρ | `size(ρ)` | `size(ρ)` | + |∂ϵ/∂σ | `size(ρ)` | `(3, size(ρ)[2:end]...)` | + |∂²ϵ/∂ρ² | `size(ρ)` | `(3, size(ρ)[2:end]...)` | + |∂²ϵ/∂ρ∂σ | `size(ρ)` | `(6, size(ρ)[2:end]...)` | + |∂²ϵ/∂σ² | `size(ρ)` | `(6, size(ρ)[2:end]...)` | + |∂³ϵ/∂ρ³ | `size(ρ)` | `(4, size(ρ)[2:end]...)` | + |∂³ϵ/∂ρ²∂σ | `size(ρ)` | `(9, size(ρ)[2:end]...)` | + |∂³ϵ/∂ρ∂σ² | `size(ρ)` | `(10, size(ρ)[2:end]...)` | + |∂³ϵ/∂σ³ | `size(ρ)` | `(12, size(ρ)[2:end]...)` | For the exact meaning of each dimension in each array, please refer to [libxc](http://octopus-code.org/wiki/Libxc) @@ -88,7 +88,7 @@ each call. ```jldoctest julia> func = XCFunctional(:lda_x, false); -julia> energy(func, Cdouble[1, 2, 3]) +julia> energy(func, [1, 2, 3]1u"rho") 3-element Array{Float64,1}: -0.738559 -0.930526 @@ -109,12 +109,12 @@ end ```jldoctest julia> ρ = Cdouble[1, 2, 3]; -julia> εxc, pot = similar(ρ), similar(ρ); +julia> ϵ, ∂ϵ_∂ρ = similar(ρ), similar(ρ); -julia> result = energy_and_potential!(func, ρ, εxc, pot) +julia> result = energy_and_potential!(func, ρ, ϵ, ∂ϵ_∂ρ) (energy = [-0.738559,-0.930526,-1.06519], potential = [-0.984745,-1.2407,-1.42025]) -julia> result.energy === εxc +julia> result.energy === ϵ true ``` diff --git a/src/LibXC.jl b/src/LibXC.jl index 330831a..7ddb3e2 100644 --- a/src/LibXC.jl +++ b/src/LibXC.jl @@ -1,3 +1,4 @@ +__precompile__() module LibXC export description, kind, family, flags, citations, spin, energy, energy! export potential, potential!, second_energy_derivative, third_energy_derivative @@ -215,6 +216,7 @@ end include("checks.jl") +include("named_tuples.jl") include("lda.jl") include("gga.jl") include("overloads.jl") diff --git a/src/gga.jl b/src/gga.jl index 4d8310f..b7977f6 100644 --- a/src/gga.jl +++ b/src/gga.jl @@ -36,8 +36,6 @@ function energy(func::AbstractLibXCFunctional, ρ::DenseArray{Cdouble}, energy!(func, ρ, σ, similar(ρ, eltype(ρ), output_size(func, ρ, 1))) end -""" Potential from GGA """ -typealias GGAPotential @NT(∂ϵ_∂ρ, ∂ϵ_∂σ) """ $(SIGNATURES) @@ -86,12 +84,6 @@ function potential(func::AbstractLibXCFunctional, ρ::DenseArray{Cdouble}, potential!(func, ρ, σ, similar(ρ), similar(ρ, eltype(ρ), output_size(func, ρ, 3))) end -""" Second derivative from GGA - -Include the second derivative of the energy with respect to ρ, σ, and both ρ and σ. -""" -typealias GGASecondDerivative @NT(∂²ϵ_∂ρ², ∂²ϵ_∂ρ∂σ, ∂²ϵ_∂σ²) - """ $(SIGNATURES) @@ -153,12 +145,6 @@ function second_energy_derivative(func::AbstractLibXCFunctional, ρ::DenseArray{ similar(ρ, eltype(ρ), output_size(func, ρ, 6))) end -""" Third derivative from GGA - -Include the third derivative of the energy with respect to ρ, σ, and both ρ and σ. -""" -typealias GGAThirdDerivative @NT(∂³ϵ_∂ρ³, ∂³ϵ_∂ρ²∂σ, ∂³ϵ_∂ρ∂σ², ∂³ϵ_∂σ³) - """ $(SIGNATURES) @@ -226,9 +212,6 @@ function third_energy_derivative(func::AbstractLibXCFunctional, ρ::DenseArray{C similar(ρ, eltype(ρ), output_size(func, ρ, 10))) end -""" Holds GGA energy and first derivatives """ -typealias GGAEnergyPotential @NT(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) - """ GGA energy and potential """ function energy_and_potential!(func::AbstractLibXCFunctional{Cdouble}, ρ::DenseArray{Units.ρ{Cdouble}}, @@ -239,7 +222,7 @@ function energy_and_potential!(func::AbstractLibXCFunctional{Cdouble}, energy_and_potential!(func, reinterpret(Cdouble, ρ), reinterpret(Cdouble, σ), reinterpret(Cdouble, ϵ), reinterpret(Cdouble, ∂ϵ_∂ρ), reinterpret(Cdouble, ∂ϵ_∂σ)) - GGAEnergyPotential(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) + GGAEnergyAndPotential(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) end function energy_and_potential!(func::AbstractLibXCFunctional, ρ::DenseArray{Cdouble}, σ::DenseArray{Cdouble}, ϵ::DenseArray{Cdouble}, @@ -255,7 +238,7 @@ function energy_and_potential!(func::AbstractLibXCFunctional, ρ::DenseArray{Cdo (Ptr{CFuncType}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}), func.c_ptr, length(ρ) / convert(Int64, spin(func)), ρ, σ, ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) - GGAEnergyPotential(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) + GGAEnergyAndPotential(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ) end function energy_and_potential(func::AbstractLibXCFunctional, ρ::DenseArray{Units.ρ{Cdouble}}, σ::DenseArray{Units.σ{Cdouble}}) @@ -270,10 +253,6 @@ function energy_and_potential(func::AbstractLibXCFunctional{Cdouble}, end -""" All outputs from LDA """ -typealias AllGGA @NT(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ, ∂²ϵ_∂ρ², ∂²ϵ_∂ρ∂σ, ∂²ϵ_∂σ², ∂³ϵ_∂ρ³, ∂³ϵ_∂ρ²∂σ, - ∂³ϵ_∂ρ∂σ², ∂³ϵ_∂σ³) - """ $(SIGNATURES) diff --git a/src/lda.jl b/src/lda.jl index cdcc4e1..b9df649 100644 --- a/src/lda.jl +++ b/src/lda.jl @@ -129,8 +129,7 @@ function third_energy_derivative(func::AbstractLibXCFunctional{Cdouble}, similar(ρ, Units.∂³ϵ_∂ρ³{Cdouble}, output_size(func, ρ, 4))) end -""" All outputs from LDA """ -typealias AllLDA @NT(ϵ, ∂ϵ_∂ρ, ∂²ϵ_∂ρ², ∂³ϵ_∂ρ³) + """ $(SIGNATURES) @@ -204,8 +203,6 @@ function lda!(func::AbstractLibXCFunctional{Cdouble}, Units.∂²ϵ_∂ρ²{Cdouble}[], Units.∂³ϵ_∂ρ³{Cdouble}[]) end -""" Energy and potential from LDA """ -typealias LDAEnergyPotential @NT(ϵ, ∂ϵ_∂ρ) """ LDA energy and first derivative """ function energy_and_potential!(func::AbstractLibXCFunctional, ρ::DenseArray{Cdouble}, ϵ::DenseArray{Cdouble}, ∂ϵ_∂ρ::DenseArray{Cdouble}) @@ -219,7 +216,7 @@ function energy_and_potential!(func::AbstractLibXCFunctional, ρ::DenseArray{Cdo (Ptr{CFuncType}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}), func.c_ptr, length(ρ) / convert(Int64, spin(func)), ρ, ϵ, ∂ϵ_∂ρ) - LDAEnergyPotential(ϵ, ∂ϵ_∂ρ) + LDAEnergyAndPotential(ϵ, ∂ϵ_∂ρ) end function energy_and_potential!(func::AbstractLibXCFunctional, @@ -228,7 +225,7 @@ function energy_and_potential!(func::AbstractLibXCFunctional, ∂ϵ_∂ρ::DenseArray{Units.∂ϵ_∂ρ{Cdouble}}) energy_and_potential!(func, reinterpret(Cdouble, ρ), reinterpret(Cdouble, ϵ), reinterpret(Cdouble, ∂ϵ_∂ρ)) - LDAEnergyPotential(ϵ, ∂ϵ_∂ρ) + LDAEnergyAndPotential(ϵ, ∂ϵ_∂ρ) end for name ∈ [:energy_and_potential, :lda, :gga] diff --git a/src/named_tuples.jl b/src/named_tuples.jl new file mode 100644 index 0000000..984e7fa --- /dev/null +++ b/src/named_tuples.jl @@ -0,0 +1,165 @@ +abstract NamedTuple + +""" All outputs from LDA """ +immutable AllLDA{T0, T1, T2, T3} <: NamedTuple + ϵ::T0 + ∂ϵ_∂ρ::T1 + ∂²ϵ_∂ρ²::T2 + ∂³ϵ_∂ρ³::T3 +end +Base.length(a::AllLDA) = 4 +function Base.getindex(a::AllLDA, index::Integer) + if index == 1 + a.ϵ + elseif index == 2 + a.∂ϵ_∂ρ + elseif index == 3 + a.∂²ϵ_∂ρ² + elseif index == 4 + a.∂³ϵ_∂ρ³ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" Energy and potential from LDA """ +immutable LDAEnergyAndPotential{T0, T1} <: NamedTuple + ϵ::T0 + ∂ϵ_∂ρ::T1 +end +Base.length(a::LDAEnergyAndPotential) = 2 +function Base.getindex(a::LDAEnergyAndPotential, index::Integer) + if index == 1 + a.ϵ + elseif index == 2 + a.∂ϵ_∂ρ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" Energy and potential from LDA """ +immutable GGAPotential{T0, T1} <: NamedTuple + ∂ϵ_∂ρ::T0 + ∂ϵ_∂σ::T1 +end +Base.length(a::GGAPotential) = 2 +function Base.getindex(a::GGAPotential, index::Integer) + if index == 1 + a.∂ϵ_∂ρ + elseif index == 2 + a.∂ϵ_∂σ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" Second derivative from GGA + +Include the second derivative of the energy with respect to ρ, σ, and both ρ and σ. +""" +immutable GGASecondDerivative{T0, T1, T2} <: NamedTuple + ∂²ϵ_∂ρ²::T0 + ∂²ϵ_∂ρ∂σ::T1 + ∂²ϵ_∂σ²::T2 +end +Base.length(a::GGASecondDerivative) = 3 +function Base.getindex(a::GGASecondDerivative, index::Integer) + if index == 1 + a.∂²ϵ_∂ρ² + elseif index == 2 + a.∂²ϵ_∂ρ∂σ + elseif index == 3 + a.∂²ϵ_∂σ² + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" Third derivative from GGA + +Include the third derivative of the energy with respect to ρ, σ, and both ρ and σ. +""" +immutable GGAThirdDerivative{T0, T1, T2, T3} <: NamedTuple + ∂³ϵ_∂ρ³::T0 + ∂³ϵ_∂ρ²∂σ::T1 + ∂³ϵ_∂ρ∂σ²::T3 + ∂³ϵ_∂σ³::T3 +end +Base.length(a::GGAThirdDerivative) = 4 +function Base.getindex(a::GGAThirdDerivative, index::Integer) + if index == 1 + a.∂³ϵ_∂ρ³ + elseif index == 2 + a.∂³ϵ_∂ρ²∂σ + elseif index == 3 + a.∂³ϵ_∂ρ∂σ² + elseif index == 3 + a.∂³ϵ_∂σ³ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" Holds GGA energy and first derivatives """ +immutable GGAEnergyAndPotential{T0, T1, T2} <: NamedTuple + ϵ::T0 + ∂ϵ_∂ρ::T1 + ∂ϵ_∂σ::T2 +end +Base.length(a::GGAEnergyAndPotential) = 3 +function Base.getindex(a::GGAEnergyAndPotential, index::Integer) + if index == 1 + a.ϵ + elseif index == 2 + a.∂ϵ_∂ρ + elseif index == 3 + a.∂ϵ_∂σ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +""" All outputs from LDA """ +immutable AllGGA{T0, T1, T2, T3, T4, T5, T6, T7, T8, T9} <: NamedTuple + ϵ::T0 + ∂ϵ_∂ρ::T1 + ∂ϵ_∂σ::T2 + ∂²ϵ_∂ρ²::T3 + ∂²ϵ_∂ρ∂σ::T4 + ∂²ϵ_∂σ²::T5 + ∂³ϵ_∂ρ³::T6 + ∂³ϵ_∂ρ²∂σ::T7 + ∂³ϵ_∂ρ∂σ²::T8 + ∂³ϵ_∂σ³::T9 +end +Base.length(a::AllGGA) = 10 +function Base.getindex(a::AllGGA, index::Integer) + if index == 1 + a.ϵ + elseif index == 2 + a.∂ϵ_∂ρ + elseif index == 3 + a.∂ϵ_∂σ + elseif index == 4 + a.∂²ϵ_∂ρ² + elseif index == 5 + a.∂²ϵ_∂ρ∂σ + elseif index == 6 + a.∂²ϵ_∂σ² + elseif index == 7 + a.∂³ϵ_∂ρ³ + elseif index == 8 + a.∂³ϵ_∂ρ²∂σ + elseif index == 9 + a.∂³ϵ_∂ρ∂σ² + elseif index == 10 + a.∂³ϵ_∂σ³ + else + throw(BoundsError("Index $index is out of bounds")) + end +end + +Base.start(iter::NamedTuple) = 1 +Base.next(iter::NamedTuple, state::Integer) = iter[state], state + 1 +Base.done(iter::NamedTuple, state::Integer) = state > length(iter)