Skip to content
This repository has been archived by the owner on Apr 24, 2023. It is now read-only.

Commit

Permalink
NamedTuples to immutable types to allow pre-compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
Mayeul d'Avezac committed Apr 17, 2017
1 parent f204191 commit cef437f
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 57 deletions.
1 change: 0 additions & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
julia 0.5
BinDeps
NamedTuples
Documenter
DocStringExtensions
Unitful
54 changes: 27 additions & 27 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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
```

Expand Down
2 changes: 2 additions & 0 deletions src/LibXC.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -215,6 +216,7 @@ end


include("checks.jl")
include("named_tuples.jl")
include("lda.jl")
include("gga.jl")
include("overloads.jl")
Expand Down
25 changes: 2 additions & 23 deletions src/gga.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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}},
Expand All @@ -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},
Expand All @@ -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}})
Expand All @@ -270,10 +253,6 @@ function energy_and_potential(func::AbstractLibXCFunctional{Cdouble},
end


""" All outputs from LDA """
typealias AllGGA @NT(ϵ, ∂ϵ_∂ρ, ∂ϵ_∂σ, ∂²ϵ_∂ρ², ∂²ϵ_∂ρ∂σ, ∂²ϵ_∂σ², ∂³ϵ_∂ρ³, ∂³ϵ_∂ρ²∂σ,
∂³ϵ_∂ρ∂σ², ∂³ϵ_∂σ³)

"""
$(SIGNATURES)
Expand Down
9 changes: 3 additions & 6 deletions src/lda.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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})
Expand All @@ -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,
Expand All @@ -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]
Expand Down
165 changes: 165 additions & 0 deletions src/named_tuples.jl
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit cef437f

Please sign in to comment.