using CoordinateTransformations: IdentityTransformation

@testset "Fractional coordinates to Cartesian coordinates" begin
    lattice = Lattice([
        1/2 0 0
        0 1/2 0
        0 0 1
    ])
    @test CartesianFromFractional(lattice)([2, 3, 1]) == [1, 3 / 2, 1]
    # Compared with "SeeK-path" example oC1 (SiTi)
    @testset "Base centered orthorhombic" begin
        a, b, c = 3.67939899, 4.15357986, 3.8236792350
        lattice = Lattice([a, -b, 0] / 2, [a, b, 0] / 2, [0, 0, c])
        f2c = CartesianFromFractional(lattice)
        @test f2c([1 / 2, 1 / 2, 1 / 2]) == [1.8396994950, 0, 1.9118396175]  # Si
        @test f2c([0, 0, 0]) == [0, 0, 0]  # Ti
        c2f = inv(f2c)
        @test c2f([1.8396994950, 0, 1.9118396175]) ≈ [1 / 2, 1 / 2, 1 / 2]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
end

# Example from http://ww1.iucr.org/iucr-top/comm/cteach/pamphlets/22/node34.html#SECTION00073300000000000000
@testset "Refer ZrSiO₄ primitive cell with origin at 2/m" begin
    𝐚ₚ, 𝐛ₚ, 𝐜ₚ = [1, 0, 0], [0, 1, 0], [1, 1, 1] // 2
    P = PrimitiveFromStandardized(hcat(𝐚ₚ, 𝐛ₚ, 𝐜ₚ))
    @test P([0, 1 // 4, 7 // 8]) == [-7, -5, 14] // 8  # The new coordinates of the first Zr atom
    @test P([0, 1 // 4, 3 // 8]) == [-3, -1, 6] // 8  # The new coordinates of the first Si atom
    @test P([0, 0.45, 0.215]) ≈ [-0.215, 0.235, 0.43]  # The new coordinates of the first O atom
    P⁻¹ = inv(P)
    @test P⁻¹([-7, -5, 14] // 8) == [0, 1 // 4, 7 // 8]
    @test P⁻¹([-3, -1, 6] // 8) == [0, 1 // 4, 3 // 8]
    @test P⁻¹([-0.215, 0.235, 0.43]) ≈ [0, 0.45, 0.215]
    @test P ∘ P⁻¹ == P⁻¹ ∘ P == IdentityTransformation()
end

@testset "Special points in the Brillouin zone" begin  # Reciprocal space transformation
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/orthorhombic.php
    @testset "Simple orthorhombic Brillouin zone" begin
        a, b, c = 2, 3, 5
        reci_lattice = inv(Lattice(a, b, c, 90, 90, 90))
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([1 / 2, 0, 0]) == [1 / a, 0, 0] / 2
        @test f2c([0, 1 / 2, 0]) == [0, 1 / b, 0] / 2
        @test f2c([0, 0, 1 / 2]) == [0, 0, 1 / c] / 2
        @test f2c([0, 1 / 2, 1 / 2]) == [0, 1 / b, 1 / c] / 2
        @test f2c([1 / 2, 1 / 2, 0]) == [1 / a, 1 / b, 0] / 2
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([1 / a, 0, 0] / 2) == [1 / 2, 0, 0]
        @test c2f([0, 1 / b, 0] / 2) == [0, 1 / 2, 0]
        @test c2f([0, 0, 1 / c] / 2) == [0, 0, 1 / 2]
        @test c2f([0, 1 / b, 1 / c] / 2) == [0, 1 / 2, 1 / 2]
        @test c2f([1 / a, 1 / b, 0] / 2) == [1 / 2, 1 / 2, 0]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # Compared with "SeeK-path" example oC1 (SiTi)
    # The results on http://lampx.tugraz.at/~hadley/ss1/bzones/orthorhombic_bc.php are wrong by a factor of 2.
    @testset "Base centered orthorhombic Brillouin zone" begin
        a, b, c = 3.67939899, 4.15357986, 3.8236792350
        reci_lattice = inv(Lattice([a, -b, 0] / 2, [a, b, 0] / 2, [0, 0, c]))
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([-1 / 2, 1 / 2, 0]) ≈ [0, 1 / b, 0] ≈ [0, 1.5127156619, 0] / 2pi  # Y'
        @test f2c([0, 0, 1 / 2]) ≈ [0, 0, 1 / 2 / c] ≈ [0, 0, 0.8216151148] / 2pi  # Z
        @test f2c([-1 / 2, 1 / 2, 1 / 2]) ≈
              [0, 1 / b, 1 / 2 / c] ≈
              [0, 1.5127156619, 0.8216151148] / 2pi  # T'
        @test f2c([0, 1 / 2, 0]) ≈
              [1 / 2 / a, 1 / 2 / b, 0] ≈
              [0.8538331021, 0.7563578310, 0] / 2pi  # S
        @test f2c([0, 1 / 2, 1 / 2]) ≈
              [1 / a, 1 / b, 1 / c] / 2 ≈
              [0.8538331021, 0.7563578310, 0.8216151148] / 2pi # R
        @test f2c([-0.4461772527, 0.5538227473, 1 / 2]) ≈
              [0.1838225731, 1.5127156619, 0.8216151148] / 2pi  # E0
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 1 / b, 0]) ≈ [-1 / 2, 1 / 2, 0]
        @test c2f([0, 0, 1 / 2 / c]) ≈ [0, 0, 1 / 2]
        @test c2f([0, 1 / b, 1 / 2 / c]) ≈ [-1 / 2, 1 / 2, 1 / 2]
        @test c2f([1 / 2 / a, 1 / 2 / b, 0]) ≈ [0, 1 / 2, 0]
        @test c2f([1 / a, 1 / b, 1 / c] / 2) ≈ [0, 1 / 2, 1 / 2]
        @test c2f([0.1838225731, 1.5127156619, 0.8216151148] / 2pi) ≈
              [-0.4461772527, 0.5538227473, 1 / 2]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/tetbc.php
    @testset "Body centered tetragonal Brillouin zone" begin
        a, c = 4, 6
        reci_lattice = inv(Lattice([a, a, -c] / 2, [a, -a, c] / 2, [-a, a, c] / 2))
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([0, 0, 0]) == [0, 0, 0]
        @test f2c([1 / 2, 0, 0]) == [1 / a, 1 / a, 0] / 2
        @test f2c([1 / 2, 1 / 2, -1 / 2]) == [1 / a, 0, 0]
        @test f2c([0, 1 / 2, 0]) == [1 / a, 0, 1 / c] / 2
        @test f2c([1, 1, 1] / 4) == [1 / a, 1 / a, 1 / c] / 2
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 0, 0]) == [0, 0, 0]
        @test c2f([1 / a, 1 / a, 0] / 2) == [1 / 2, 0, 0]
        @test c2f([1 / a, 0, 0]) == [1 / 2, 1 / 2, -1 / 2]
        @test c2f([1 / a, 0, 1 / c] / 2) ≈ [0, 1 / 2, 0]
        @test c2f([1 / a, 1 / a, 1 / c] / 2) == [1, 1, 1] / 4
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/hexagonal.php
    @testset "Simple hexagonal Brillouin zone" begin
        a, c = 2, 3.2
        reci_lattice = inv(Lattice([a, 0, 0], [a / 2, sqrt(3) / 2 * a, 0], [0, 0, c]))
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([0, 0, 0]) == [0, 0, 0]  # Γ
        @test f2c([1 / 2, 0, 0]) ≈ [1 / a, -1 / sqrt(3) / a, 0] / 2  # M
        @test f2c([0, 0, 1 / 2]) ≈ [0, 0, 1 / c] / 2  # A
        @test f2c([2 / 3, 1 / 3, 0]) ≈ [2 / 3 / a, 0, 0]  # K
        @test f2c([2 / 3, 1 / 3, 1 / 2]) ≈ [2 / 3 / a, 0, 1 / 2 / c]  # H
        @test f2c([1 / 2, 0, 1 / 2]) ≈ [1 / a, -1 / sqrt(3) / a, 1 / c] / 2  # L
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 0, 0]) == [0, 0, 0]
        @test c2f([1 / a, -1 / sqrt(3) / a, 0] / 2) ≈ [1 / 2, 0, 0]
        @test c2f([0, 0, 1 / c] / 2) == [0, 0, 1 / 2]
        @test c2f([2 / 3 / a, 0, 0]) == [2 / 3, 1 / 3, 0]
        @test c2f([2 / 3 / a, 0, 1 / 2 / c]) == [2 / 3, 1 / 3, 1 / 2]
        @test c2f([1 / a, -1 / sqrt(3) / a, 1 / c] / 2) ≈ [1 / 2, 0, 1 / 2]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/sc.php
    @testset "Simple cubic Brillouin zone" begin
        a = 4
        reci_lattice = inv(Lattice(a, a, a, 90, 90, 90))
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([0, 0, 0]) == [0, 0, 0]
        @test f2c([1 / 2, 1 / 2, 0]) == [1 / a, 1 / a, 0] / 2
        @test f2c([1 / 2, 1 / 2, 1 / 2]) == [1 / a, 1 / a, 1 / a] / 2
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 0, 0]) == [0, 0, 0]
        @test c2f([1 / a, 1 / a, 0] / 2) == [1 / 2, 1 / 2, 0]
        @test c2f([1 / a, 1 / a, 1 / a] / 2) == [1 / 2, 1 / 2, 1 / 2]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/fcc.php
    @testset "Face centered cubic Brillouin zone" begin
        a = 4
        reci_lattice = inv(Lattice([
            1 1 0
            0 1 1
            1 0 1
        ]) * a / 2)
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([0, 0, 0]) == [0, 0, 0]
        @test f2c([0, 1 / 2, 1 / 2]) == [0, 1 / a, 0]
        @test f2c([1 / 2, 1 / 2, 1 / 2]) == [1 / a, 1 / a, 1 / a] / 2
        @test f2c([1 / 4, 3 / 4, 1 / 2]) == [1 / 2 / a, 1 / a, 0]
        @test f2c([1 / 4, 5 / 8, 5 / 8]) == [1 / 2 / a, 2 / a, 1 / 2 / a] / 2
        @test f2c([3 / 8, 3 / 4, 3 / 8]) == [3 / 2 / a, 3 / 2 / a, 0] / 2
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 0, 0]) == [0, 0, 0]
        @test f2c([0, 1 / 2, 1 / 2]) == [0, 1 / a, 0]
        @test f2c([1 / 2, 1 / 2, 1 / 2]) == [1 / a, 1 / a, 1 / a] / 2
        @test c2f([1 / 2 / a, 1 / a, 0]) == [1 / 4, 3 / 4, 1 / 2]
        @test c2f([1 / 2 / a, 2 / a, 1 / 2 / a] / 2) == [1 / 4, 5 / 8, 5 / 8]
        @test c2f([3 / 2 / a, 3 / 2 / a, 0] / 2) == [3 / 8, 3 / 4, 3 / 8]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
    # See http://lampx.tugraz.at/~hadley/ss1/bzones/bcc.php
    @testset "Body centered cubic Brillouin zone" begin
        a = 4
        reci_lattice = inv(Lattice([
            1 -1 1
            1 1 -1
            -1 1 1
        ]) * a / 2)
        f2c = CartesianFromFractional(reci_lattice)
        @test f2c([0, 0, 0]) == [0, 0, 0]
        @test f2c([-1 / 2, 1 / 2, 1 / 2]) == [0, 0, 1 / a]
        @test f2c([1 / 4, 1 / 4, 1 / 4]) == [1 / a, 1 / a, 1 / a] / 2
        @test f2c([0, 1 / 2, 0]) == [0, 1 / a, 1 / a] / 2
        c2f = FractionalFromCartesian(reci_lattice)
        @test c2f([0, 0, 0]) == [0, 0, 0]
        @test c2f([0, 0, 1 / a]) == [-1 / 2, 1 / 2, 1 / 2]
        @test c2f([1 / a, 1 / a, 1 / a] / 2) == [1 / 4, 1 / 4, 1 / 4]
        @test c2f([0, 1 / a, 1 / a] / 2) == [0, 1 / 2, 0]
        @test c2f ∘ f2c == f2c ∘ c2f == IdentityTransformation()
    end
end

@testset "Test coordinate transformation with units" begin
    alat = 8.8097
    reci_lattice = inv(
        Lattice(
            [
                -2.739741805 2.739741805 2.739741805
                2.739741805 -2.739741805 2.739741805
                2.592418910 2.592418910 -2.592418910
            ] / alat * u"angstrom" .|> u"bohr",
        ),
    )
    # Compared with Quantum ESPRESSO results
    qe_crystal =
        [
            0.0 0.0 0.0
            -0.0 -0.0 0.016129
            0.0 -0.0 0.0322581
            -0.0 0.0 0.0483871
            0.0 -0.0 0.0645161
            -0.0 0.0 0.0806452
            -0.0 -0.0 0.0967742
            -0.0 0.0 0.1129032
            0.0 -0.0 0.1290323
            -0.0 0.0 0.1451613
            -0.0 0.0 0.1612903
            -0.0 -0.0 0.1774194
            0.0 -0.0 0.1935484
            -0.0 -0.0 0.2096774
            -0.0 0.0 0.2258065
            -0.0 0.0 0.2419355
            -0.0 -0.0 0.2580645
            -0.0 -0.0 0.2741935
            -0.0 0.0 0.2903226
            0.0 -0.0 0.3064516
            -0.0 0.0 0.3225806
            0.0 -0.0 0.3387097
            -0.0 -0.0 0.3548387
            -0.0 -0.0 0.3709677
            0.0 -0.0 0.3870968
            -0.0 0.0 0.4032258
            0.0 -0.0 0.4193548
            -0.0 -0.0 0.4354839
            -0.0 0.0 0.4516129
            -0.0 -0.0 0.4677419
            -0.0 -0.0 0.483871
            0.0 -0.0 0.5
            -0.016129 0.016129 0.5
            -0.0322581 0.0322581 0.5
            -0.0483871 0.0483871 0.5
            -0.0645161 0.0645161 0.5
            -0.0806452 0.0806452 0.5
            -0.0967742 0.0967742 0.5
            -0.1129032 0.1129032 0.5
            -0.1290323 0.1290323 0.5
            -0.1451613 0.1451613 0.5
            -0.1612903 0.1612903 0.5
            -0.1774194 0.1774194 0.5
            -0.1935484 0.1935484 0.5
            -0.2096774 0.2096774 0.5
            -0.2258065 0.2258065 0.5
            -0.2419355 0.2419355 0.5
            -0.2580645 0.2580645 0.5
            -0.2741935 0.2741935 0.5
            -0.2903226 0.2903226 0.5
            -0.3064516 0.3064516 0.5
            -0.3225806 0.3225806 0.5
            -0.3387097 0.3387097 0.5
            -0.3548387 0.3548387 0.5
            -0.3709677 0.3709677 0.5
            -0.3870968 0.3870968 0.5
            -0.4032258 0.4032258 0.5
            -0.4193548 0.4193548 0.5
            -0.4354839 0.4354839 0.5
            -0.4516129 0.4516129 0.5
            -0.4677419 0.4677419 0.5
            -0.483871 0.483871 0.5
            -0.5 0.5 0.5
            -0.4886364 0.4886364 0.4886364
            -0.4772727 0.4772727 0.4772727
            -0.4659091 0.4659091 0.4659091
            -0.4545455 0.4545455 0.4545455
            -0.4431818 0.4431818 0.4431818
            -0.4318182 0.4318182 0.4318182
            -0.4204545 0.4204545 0.4204545
            -0.4090909 0.4090909 0.4090909
            -0.3977273 0.3977273 0.3977273
            -0.3863636 0.3863636 0.3863636
            -0.375 0.375 0.375
            -0.3636364 0.3636364 0.3636364
            -0.3522727 0.3522727 0.3522727
            -0.3409091 0.3409091 0.3409091
            -0.3295455 0.3295455 0.3295455
            -0.3181818 0.3181818 0.3181818
            -0.3068182 0.3068182 0.3068182
            -0.2954545 0.2954545 0.2954545
            -0.2840909 0.2840909 0.2840909
            -0.2727273 0.2727273 0.2727273
            -0.2613636 0.2613636 0.2613636
            -0.25 0.25 0.25
            -0.2386364 0.2386364 0.2386364
            -0.2272727 0.2272727 0.2272727
            -0.2159091 0.2159091 0.2159091
            -0.2045455 0.2045455 0.2045455
            -0.1931818 0.1931818 0.1931818
            -0.1818182 0.1818182 0.1818182
            -0.1704545 0.1704545 0.1704545
            -0.1590909 0.1590909 0.1590909
            -0.1477273 0.1477273 0.1477273
            -0.1363636 0.1363636 0.1363636
            -0.125 0.125 0.125
            -0.1136364 0.1136364 0.1136364
            -0.1022727 0.1022727 0.1022727
            -0.0909091 0.0909091 0.0909091
            -0.0795455 0.0795455 0.0795455
            -0.0681818 0.0681818 0.0681818
            -0.0568182 0.0568182 0.0568182
            -0.0454545 0.0454545 0.0454545
            -0.0340909 0.0340909 0.0340909
            -0.0227273 0.0227273 0.0227273
            -0.0113636 0.0113636 0.0113636
            0.0 0.0 0.0
            0.010769 0.010769 -0.010769
            0.021538 0.021538 -0.021538
            0.032307 0.032307 -0.032307
            0.0430761 0.0430761 -0.0430761
            0.0538451 0.0538451 -0.0538451
            0.0646141 0.0646141 -0.0646141
            0.0753831 0.0753831 -0.0753831
            0.0861521 0.0861521 -0.0861521
            0.0969211 0.0969211 -0.0969211
            0.1076901 0.1076901 -0.1076901
            0.1184591 0.1184591 -0.1184591
            0.1292282 0.1292282 -0.1292282
            0.1399972 0.1399972 -0.1399972
            0.1507662 0.1507662 -0.1507662
            0.1615352 0.1615352 -0.1615352
            0.1723042 0.1723042 -0.1723042
            0.1830732 0.1830732 -0.1830732
            0.1938422 0.1938422 -0.1938422
            0.2046113 0.2046113 -0.2046113
            0.2153803 0.2153803 -0.2153803
            0.2261493 0.2261493 -0.2261493
            0.2369183 0.2369183 -0.2369183
            0.2476873 0.2476873 -0.2476873
            0.2584563 0.2584563 -0.2584563
            0.2692253 0.2692253 -0.2692253
            0.2799944 0.2799944 -0.2799944
            0.2907634 0.2907634 -0.2907634
            0.3015324 0.3015324 -0.3015324
            0.3123014 0.3123014 -0.3123014
            0.3230704 0.3230704 -0.3230704
            0.3338394 0.3338394 -0.3338394
            0.3446084 0.3446084 -0.3446084
            0.3553774 0.3553774 -0.3553774
            0.3661465 0.3661465 -0.3661465
            0.3769155 0.3769155 -0.3769155
            0.3876845 0.3876845 -0.3876845
            0.3984535 0.3984535 -0.3984535
            0.4092225 0.4092225 -0.4092225
            0.4199915 0.4199915 -0.4199915
            0.4307605 0.4307605 -0.4307605
            0.4415296 0.4415296 -0.4415296
            0.4522986 0.4522986 -0.4522986
            0.4630676 0.4630676 -0.4630676
            0.4738366 0.4738366 -0.4738366
            -0.4738366 0.5261634 0.4738366
            -0.5 0.5 0.5
            0.0 -0.0 0.5
            0.0108696 0.0108696 0.4891304
            0.0217391 0.0217391 0.4782609
            0.0326087 0.0326087 0.4673913
            0.0434783 0.0434783 0.4565217
            0.0543478 0.0543478 0.4456522
            0.0652174 0.0652174 0.4347826
            0.076087 0.076087 0.423913
            0.0869565 0.0869565 0.4130435
            0.0978261 0.0978261 0.4021739
            0.1086957 0.1086957 0.3913043
            0.1195652 0.1195652 0.3804348
            0.1304348 0.1304348 0.3695652
            0.1413043 0.1413043 0.3586957
            0.1521739 0.1521739 0.3478261
            0.1630435 0.1630435 0.3369565
            0.173913 0.173913 0.326087
            0.1847826 0.1847826 0.3152174
            0.1956522 0.1956522 0.3043478
            0.2065217 0.2065217 0.2934783
            0.2173913 0.2173913 0.2826087
            0.2282609 0.2282609 0.2717391
            0.2391304 0.2391304 0.2608696
            0.25 0.25 0.25
            0.2380952 0.2619048 0.2380952
            0.2261905 0.2738095 0.2261905
            0.2142857 0.2857143 0.2142857
            0.202381 0.297619 0.202381
            0.1904762 0.3095238 0.1904762
            0.1785714 0.3214286 0.1785714
            0.1666667 0.3333333 0.1666667
            0.1547619 0.3452381 0.1547619
            0.1428571 0.3571429 0.1428571
            0.1309524 0.3690476 0.1309524
            0.1190476 0.3809524 0.1190476
            0.1071429 0.3928571 0.1071429
            0.0952381 0.4047619 0.0952381
            0.0833333 0.4166667 0.0833333
            0.0714286 0.4285714 0.0714286
            0.0595238 0.4404762 0.0595238
            0.047619 0.452381 0.047619
            0.0357143 0.4642857 0.0357143
            0.0238095 0.4761905 0.0238095
            0.0119048 0.4880952 0.0119048
            -0.0 0.5 0.0
            -0.0 0.484375 0.0
            -0.0 0.46875 0.0
            0.0 0.453125 -0.0
            -0.0 0.4375 0.0
            -0.0 0.421875 0.0
            -0.0 0.40625 0.0
            0.0 0.390625 -0.0
            -0.0 0.375 0.0
            -0.0 0.359375 0.0
            -0.0 0.34375 0.0
            -0.0 0.328125 0.0
            0.0 0.3125 0.0
            -0.0 0.296875 0.0
            -0.0 0.28125 0.0
            0.0 0.265625 0.0
            -0.0 0.25 0.0
            -0.0 0.234375 0.0
            -0.0 0.21875 0.0
            -0.0 0.203125 0.0
            -0.0 0.1875 0.0
            -0.0 0.171875 0.0
            0.0 0.15625 0.0
            -0.0 0.140625 0.0
            -0.0 0.125 0.0
            -0.0 0.109375 0.0
            -0.0 0.09375 0.0
            0.0 0.078125 0.0
            -0.0 0.0625 0.0
            -0.0 0.046875 0.0
            -0.0 0.03125 0.0
            -0.0 0.015625 0.0
            0.0 0.0 0.0
            0.0 0.0 -0.016129
            -0.0 0.0 -0.0322581
            0.0 -0.0 -0.0483871
            -0.0 0.0 -0.0645161
            0.0 -0.0 -0.0806452
            0.0 0.0 -0.0967742
            0.0 -0.0 -0.1129032
            -0.0 0.0 -0.1290323
            0.0 -0.0 -0.1451613
            0.0 -0.0 -0.1612903
            0.0 0.0 -0.1774194
            -0.0 0.0 -0.1935484
            0.0 0.0 -0.2096774
            0.0 -0.0 -0.2258065
            0.0 -0.0 -0.2419355
            0.0 0.0 -0.2580645
            0.0 0.0 -0.2741935
            0.0 -0.0 -0.2903226
            -0.0 0.0 -0.3064516
            0.0 -0.0 -0.3225806
            -0.0 0.0 -0.3387097
            0.0 0.0 -0.3548387
            0.0 0.0 -0.3709677
            -0.0 0.0 -0.3870968
            0.0 -0.0 -0.4032258
            -0.0 0.0 -0.4193548
            0.0 0.0 -0.4354839
            0.0 -0.0 -0.4516129
            0.0 0.0 -0.4677419
            0.0 0.0 -0.483871
            -0.0 0.0 -0.5
            0.016129 -0.016129 -0.5
            0.0322581 -0.0322581 -0.5
            0.0483871 -0.0483871 -0.5
            0.0645161 -0.0645161 -0.5
            0.0806452 -0.0806452 -0.5
            0.0967742 -0.0967742 -0.5
            0.1129032 -0.1129032 -0.5
            0.1290323 -0.1290323 -0.5
            0.1451613 -0.1451613 -0.5
            0.1612903 -0.1612903 -0.5
            0.1774194 -0.1774194 -0.5
            0.1935484 -0.1935484 -0.5
            0.2096774 -0.2096774 -0.5
            0.2258065 -0.2258065 -0.5
            0.2419355 -0.2419355 -0.5
            0.2580645 -0.2580645 -0.5
            0.2741935 -0.2741935 -0.5
            0.2903226 -0.2903226 -0.5
            0.3064516 -0.3064516 -0.5
            0.3225806 -0.3225806 -0.5
            0.3387097 -0.3387097 -0.5
            0.3548387 -0.3548387 -0.5
            0.3709677 -0.3709677 -0.5
            0.3870968 -0.3870968 -0.5
            0.4032258 -0.4032258 -0.5
            0.4193548 -0.4193548 -0.5
            0.4354839 -0.4354839 -0.5
            0.4516129 -0.4516129 -0.5
            0.4677419 -0.4677419 -0.5
            0.483871 -0.483871 -0.5
            0.5 -0.5 -0.5
            0.4886364 -0.4886364 -0.4886364
            0.4772727 -0.4772727 -0.4772727
            0.4659091 -0.4659091 -0.4659091
            0.4545455 -0.4545455 -0.4545455
            0.4431818 -0.4431818 -0.4431818
            0.4318182 -0.4318182 -0.4318182
            0.4204545 -0.4204545 -0.4204545
            0.4090909 -0.4090909 -0.4090909
            0.3977273 -0.3977273 -0.3977273
            0.3863636 -0.3863636 -0.3863636
            0.375 -0.375 -0.375
            0.3636364 -0.3636364 -0.3636364
            0.3522727 -0.3522727 -0.3522727
            0.3409091 -0.3409091 -0.3409091
            0.3295455 -0.3295455 -0.3295455
            0.3181818 -0.3181818 -0.3181818
            0.3068182 -0.3068182 -0.3068182
            0.2954545 -0.2954545 -0.2954545
            0.2840909 -0.2840909 -0.2840909
            0.2727273 -0.2727273 -0.2727273
            0.2613636 -0.2613636 -0.2613636
            0.25 -0.25 -0.25
            0.2386364 -0.2386364 -0.2386364
            0.2272727 -0.2272727 -0.2272727
            0.2159091 -0.2159091 -0.2159091
            0.2045455 -0.2045455 -0.2045455
            0.1931818 -0.1931818 -0.1931818
            0.1818182 -0.1818182 -0.1818182
            0.1704545 -0.1704545 -0.1704545
            0.1590909 -0.1590909 -0.1590909
            0.1477273 -0.1477273 -0.1477273
            0.1363636 -0.1363636 -0.1363636
            0.125 -0.125 -0.125
            0.1136364 -0.1136364 -0.1136364
            0.1022727 -0.1022727 -0.1022727
            0.0909091 -0.0909091 -0.0909091
            0.0795455 -0.0795455 -0.0795455
            0.0681818 -0.0681818 -0.0681818
            0.0568182 -0.0568182 -0.0568182
            0.0454545 -0.0454545 -0.0454545
            0.0340909 -0.0340909 -0.0340909
            0.0227273 -0.0227273 -0.0227273
            0.0113636 -0.0113636 -0.0113636
            0.0 0.0 0.0
            -0.010769 -0.010769 0.010769
            -0.021538 -0.021538 0.021538
            -0.032307 -0.032307 0.032307
            -0.0430761 -0.0430761 0.0430761
            -0.0538451 -0.0538451 0.0538451
            -0.0646141 -0.0646141 0.0646141
            -0.0753831 -0.0753831 0.0753831
            -0.0861521 -0.0861521 0.0861521
            -0.0969211 -0.0969211 0.0969211
            -0.1076901 -0.1076901 0.1076901
            -0.1184591 -0.1184591 0.1184591
            -0.1292282 -0.1292282 0.1292282
            -0.1399972 -0.1399972 0.1399972
            -0.1507662 -0.1507662 0.1507662
            -0.1615352 -0.1615352 0.1615352
            -0.1723042 -0.1723042 0.1723042
            -0.1830732 -0.1830732 0.1830732
            -0.1938422 -0.1938422 0.1938422
            -0.2046113 -0.2046113 0.2046113
            -0.2153803 -0.2153803 0.2153803
            -0.2261493 -0.2261493 0.2261493
            -0.2369183 -0.2369183 0.2369183
            -0.2476873 -0.2476873 0.2476873
            -0.2584563 -0.2584563 0.2584563
            -0.2692253 -0.2692253 0.2692253
            -0.2799944 -0.2799944 0.2799944
            -0.2907634 -0.2907634 0.2907634
            -0.3015324 -0.3015324 0.3015324
            -0.3123014 -0.3123014 0.3123014
            -0.3230704 -0.3230704 0.3230704
            -0.3338394 -0.3338394 0.3338394
            -0.3446084 -0.3446084 0.3446084
            -0.3553774 -0.3553774 0.3553774
            -0.3661465 -0.3661465 0.3661465
            -0.3769155 -0.3769155 0.3769155
            -0.3876845 -0.3876845 0.3876845
            -0.3984535 -0.3984535 0.3984535
            -0.4092225 -0.4092225 0.4092225
            -0.4199915 -0.4199915 0.4199915
            -0.4307605 -0.4307605 0.4307605
            -0.4415296 -0.4415296 0.4415296
            -0.4522986 -0.4522986 0.4522986
            -0.4630676 -0.4630676 0.4630676
            -0.4738366 -0.4738366 0.4738366
            0.4738366 -0.5261634 -0.4738366
            0.5 -0.5 -0.5
            -0.0 0.0 -0.5
            -0.0108696 -0.0108696 -0.4891304
            -0.0217391 -0.0217391 -0.4782609
            -0.0326087 -0.0326087 -0.4673913
            -0.0434783 -0.0434783 -0.4565217
            -0.0543478 -0.0543478 -0.4456522
            -0.0652174 -0.0652174 -0.4347826
            -0.076087 -0.076087 -0.423913
            -0.0869565 -0.0869565 -0.4130435
            -0.0978261 -0.0978261 -0.4021739
            -0.1086957 -0.1086957 -0.3913043
            -0.1195652 -0.1195652 -0.3804348
            -0.1304348 -0.1304348 -0.3695652
            -0.1413043 -0.1413043 -0.3586957
            -0.1521739 -0.1521739 -0.3478261
            -0.1630435 -0.1630435 -0.3369565
            -0.173913 -0.173913 -0.326087
            -0.1847826 -0.1847826 -0.3152174
            -0.1956522 -0.1956522 -0.3043478
            -0.2065217 -0.2065217 -0.2934783
            -0.2173913 -0.2173913 -0.2826087
            -0.2282609 -0.2282609 -0.2717391
            -0.2391304 -0.2391304 -0.2608696
            -0.25 -0.25 -0.25
            -0.2380952 -0.2619048 -0.2380952
            -0.2261905 -0.2738095 -0.2261905
            -0.2142857 -0.2857143 -0.2142857
            -0.202381 -0.297619 -0.202381
            -0.1904762 -0.3095238 -0.1904762
            -0.1785714 -0.3214286 -0.1785714
            -0.1666667 -0.3333333 -0.1666667
            -0.1547619 -0.3452381 -0.1547619
            -0.1428571 -0.3571429 -0.1428571
            -0.1309524 -0.3690476 -0.1309524
            -0.1190476 -0.3809524 -0.1190476
            -0.1071429 -0.3928571 -0.1071429
            -0.0952381 -0.4047619 -0.0952381
            -0.0833333 -0.4166667 -0.0833333
            -0.0714286 -0.4285714 -0.0714286
            -0.0595238 -0.4404762 -0.0595238
            -0.047619 -0.452381 -0.047619
            -0.0357143 -0.4642857 -0.0357143
            -0.0238095 -0.4761905 -0.0238095
            -0.0119048 -0.4880952 -0.0119048
            0.0 -0.5 -0.0
            0.0 -0.484375 -0.0
            0.0 -0.46875 -0.0
            -0.0 -0.453125 0.0
            0.0 -0.4375 -0.0
            0.0 -0.421875 -0.0
            0.0 -0.40625 -0.0
            -0.0 -0.390625 0.0
            0.0 -0.375 -0.0
            0.0 -0.359375 -0.0
            0.0 -0.34375 -0.0
            0.0 -0.328125 -0.0
            -0.0 -0.3125 -0.0
            0.0 -0.296875 -0.0
            0.0 -0.28125 -0.0
            -0.0 -0.265625 -0.0
            0.0 -0.25 -0.0
            0.0 -0.234375 -0.0
            0.0 -0.21875 -0.0
            0.0 -0.203125 -0.0
            0.0 -0.1875 -0.0
            0.0 -0.171875 -0.0
            -0.0 -0.15625 -0.0
            0.0 -0.140625 -0.0
            0.0 -0.125 -0.0
            0.0 -0.109375 -0.0
            0.0 -0.09375 -0.0
            -0.0 -0.078125 -0.0
            0.0 -0.0625 -0.0
            0.0 -0.046875 -0.0
            0.0 -0.03125 -0.0
            0.0 -0.015625 -0.0
            0.0 0.0 0.0
        ]'
    qe_cartesian =
        [
            0.0 0.0 0.0
            0.0137224 0.0137224 -0.0
            0.0274447 0.0274447 -0.0
            0.0411671 0.0411671 -0.0
            0.0548894 0.0548894 -0.0
            0.0686118 0.0686118 -0.0
            0.0823341 0.0823341 -0.0
            0.0960565 0.0960565 -0.0
            0.1097788 0.1097788 -0.0
            0.1235012 0.1235012 -0.0
            0.1372235 0.1372235 -0.0
            0.1509459 0.1509459 -0.0
            0.1646682 0.1646682 -0.0
            0.1783906 0.1783906 -0.0
            0.1921129 0.1921129 -0.0
            0.2058353 0.2058353 -0.0
            0.2195576 0.2195576 -0.0
            0.23328 0.23328 -0.0
            0.2470023 0.2470023 -0.0
            0.2607247 0.2607247 -0.0
            0.2744471 0.2744471 -0.0
            0.2881694 0.2881694 -0.0
            0.3018918 0.3018918 -0.0
            0.3156141 0.3156141 -0.0
            0.3293365 0.3293365 -0.0
            0.3430588 0.3430588 -0.0
            0.3567812 0.3567812 -0.0
            0.3705035 0.3705035 -0.0
            0.3842259 0.3842259 -0.0
            0.3979482 0.3979482 -0.0
            0.4116706 0.4116706 -0.0
            0.4253929 0.4253929 -0.0
            0.4391153 0.4116706 -0.0
            0.4528376 0.3979482 -0.0
            0.46656 0.3842259 -0.0
            0.4802823 0.3705035 -0.0
            0.4940047 0.3567812 -0.0
            0.5077271 0.3430588 -0.0
            0.5214494 0.3293365 -0.0
            0.5351718 0.3156141 -0.0
            0.5488941 0.3018918 -0.0
            0.5626165 0.2881694 -0.0
            0.5763388 0.2744471 -0.0
            0.5900612 0.2607247 -0.0
            0.6037835 0.2470023 -0.0
            0.6175059 0.23328 -0.0
            0.6312282 0.2195576 -0.0
            0.6449506 0.2058353 -0.0
            0.6586729 0.1921129 -0.0
            0.6723953 0.1783906 -0.0
            0.6861176 0.1646682 -0.0
            0.69984 0.1509459 0.0
            0.7135623 0.1372235 -0.0
            0.7272847 0.1235012 -0.0
            0.741007 0.1097788 0.0
            0.7547294 0.0960565 -0.0
            0.7684518 0.0823341 -0.0
            0.7821741 0.0686118 0.0
            0.7958965 0.0548894 -0.0
            0.8096188 0.0411671 -0.0
            0.8233412 0.0274447 0.0
            0.8370635 0.0137224 -0.0
            0.8507859 0.0 -0.0
            0.8314498 -0.0 -0.0
            0.8121138 0.0 0.0
            0.7927777 -0.0 -0.0
            0.7734417 0.0 -0.0
            0.7541057 -0.0 -0.0
            0.7347696 -0.0 -0.0
            0.7154336 -0.0 -0.0
            0.6960975 0.0 0.0
            0.6767615 0.0 -0.0
            0.6574254 -0.0 -0.0
            0.6380894 0.0 -0.0
            0.6187534 -0.0 0.0
            0.5994173 0.0 0.0
            0.5800813 0.0 -0.0
            0.5607452 -0.0 -0.0
            0.5414092 -0.0 -0.0
            0.5220731 -0.0 -0.0
            0.5027371 0.0 0.0
            0.4834011 0.0 0.0
            0.464065 -0.0 0.0
            0.444729 -0.0 -0.0
            0.4253929 0.0 -0.0
            0.4060569 0.0 0.0
            0.3867209 0.0 -0.0
            0.3673848 -0.0 -0.0
            0.3480488 -0.0 -0.0
            0.3287127 -0.0 -0.0
            0.3093767 -0.0 0.0
            0.2900406 -0.0 0.0
            0.2707046 -0.0 -0.0
            0.2513686 0.0 0.0
            0.2320325 0.0 -0.0
            0.2126965 0.0 -0.0
            0.1933604 -0.0 -0.0
            0.1740244 0.0 0.0
            0.1546883 -0.0 0.0
            0.1353523 -0.0 -0.0
            0.1160163 0.0 -0.0
            0.0966802 -0.0 -0.0
            0.0773442 -0.0 -0.0
            0.0580081 0.0 -0.0
            0.0386721 0.0 -0.0
            0.019336 -0.0 -0.0
            0.0 0.0 0.0
            -0.0 -0.0 0.0193656
            -0.0 -0.0 0.0387312
            -0.0 -0.0 0.0580968
            -0.0 -0.0 0.0774623
            -0.0 -0.0 0.0968279
            -0.0 -0.0 0.1161935
            0.0 0.0 0.1355591
            -0.0 -0.0 0.1549247
            0.0 0.0 0.1742903
            -0.0 -0.0 0.1936559
            0.0 0.0 0.2130214
            -0.0 -0.0 0.232387
            -0.0 -0.0 0.2517526
            0.0 0.0 0.2711182
            0.0 0.0 0.2904838
            0.0 0.0 0.3098494
            -0.0 -0.0 0.329215
            -0.0 -0.0 0.3485805
            0.0 0.0 0.3679461
            0.0 0.0 0.3873117
            0.0 0.0 0.4066773
            -0.0 -0.0 0.4260429
            -0.0 -0.0 0.4454085
            0.0 0.0 0.4647741
            0.0 0.0 0.4841397
            0.0 0.0 0.5035052
            -0.0 -0.0 0.5228708
            -0.0 -0.0 0.5422364
            0.0 0.0 0.561602
            -0.0 -0.0 0.5809676
            0.0 0.0 0.6003332
            0.0 0.0 0.6196988
            0.0 0.0 0.6390643
            -0.0 -0.0 0.6584299
            0.0 0.0 0.6777955
            -0.0 -0.0 0.6971611
            0.0 0.0 0.7165267
            0.0 0.0 0.7358923
            -0.0 -0.0 0.7552579
            0.0 0.0 0.7746234
            -0.0 -0.0 0.793989
            0.0 0.0 0.8133546
            -0.0 -0.0 0.8327202
            -0.0 -0.0 0.8520858
            0.8507859 0.0 0.0470488
            0.8507859 0.0 -0.0
            0.4253929 0.4253929 -0.0
            0.4253929 0.4253929 0.0195464
            0.4253929 0.4253929 0.0390928
            0.4253929 0.4253929 0.0586392
            0.4253929 0.4253929 0.0781856
            0.4253929 0.4253929 0.097732
            0.4253929 0.4253929 0.1172784
            0.4253929 0.4253929 0.1368248
            0.4253929 0.4253929 0.1563712
            0.4253929 0.4253929 0.1759176
            0.4253929 0.4253929 0.1954641
            0.4253929 0.4253929 0.2150105
            0.4253929 0.4253929 0.2345569
            0.4253929 0.4253929 0.2541033
            0.4253929 0.4253929 0.2736497
            0.4253929 0.4253929 0.2931961
            0.4253929 0.4253929 0.3127425
            0.4253929 0.4253929 0.3322889
            0.4253929 0.4253929 0.3518353
            0.4253929 0.4253929 0.3713817
            0.4253929 0.4253929 0.3909281
            0.4253929 0.4253929 0.4104745
            0.4253929 0.4253929 0.4300209
            0.4253929 0.4253929 0.4495673
            0.4253929 0.4051361 0.4495673
            0.4253929 0.3848793 0.4495673
            0.4253929 0.3646225 0.4495673
            0.4253929 0.3443657 0.4495673
            0.4253929 0.3241089 0.4495673
            0.4253929 0.3038521 0.4495673
            0.4253929 0.2835953 0.4495673
            0.4253929 0.2633385 0.4495673
            0.4253929 0.2430817 0.4495673
            0.4253929 0.2228249 0.4495673
            0.4253929 0.2025681 0.4495673
            0.4253929 0.1823113 0.4495673
            0.4253929 0.1620545 0.4495673
            0.4253929 0.1417976 0.4495673
            0.4253929 0.1215408 0.4495673
            0.4253929 0.101284 0.4495673
            0.4253929 0.0810272 0.4495673
            0.4253929 0.0607704 0.4495673
            0.4253929 0.0405136 0.4495673
            0.4253929 0.0202568 0.4495673
            0.4253929 0.0 0.4495673
            0.4120994 0.0 0.4355183
            0.3988059 0.0 0.4214694
            0.3855123 0.0 0.4074204
            0.3722188 0.0 0.3933714
            0.3589253 0.0 0.3793224
            0.3456318 0.0 0.3652734
            0.3323382 0.0 0.3512245
            0.3190447 0.0 0.3371755
            0.3057512 0.0 0.3231265
            0.2924576 0.0 0.3090775
            0.2791641 0.0 0.2950286
            0.2658706 0.0 0.2809796
            0.2525771 0.0 0.2669306
            0.2392835 0.0 0.2528816
            0.22599 0.0 0.2388326
            0.2126965 0.0 0.2247837
            0.1994029 0.0 0.2107347
            0.1861094 0.0 0.1966857
            0.1728159 0.0 0.1826367
            0.1595224 0.0 0.1685877
            0.1462288 0.0 0.1545388
            0.1329353 0.0 0.1404898
            0.1196418 0.0 0.1264408
            0.1063482 0.0 0.1123918
            0.0930547 0.0 0.0983429
            0.0797612 0.0 0.0842939
            0.0664676 0.0 0.0702449
            0.0531741 0.0 0.0561959
            0.0398806 0.0 0.0421469
            0.0265871 0.0 0.028098
            0.0132935 0.0 0.014049
            0.0 0.0 0.0
            -0.0137224 -0.0137224 0.0
            -0.0274447 -0.0274447 0.0
            -0.0411671 -0.0411671 0.0
            -0.0548894 -0.0548894 0.0
            -0.0686118 -0.0686118 0.0
            -0.0823341 -0.0823341 0.0
            -0.0960565 -0.0960565 0.0
            -0.1097788 -0.1097788 0.0
            -0.1235012 -0.1235012 0.0
            -0.1372235 -0.1372235 0.0
            -0.1509459 -0.1509459 0.0
            -0.1646682 -0.1646682 0.0
            -0.1783906 -0.1783906 0.0
            -0.1921129 -0.1921129 0.0
            -0.2058353 -0.2058353 0.0
            -0.2195576 -0.2195576 0.0
            -0.23328 -0.23328 0.0
            -0.2470023 -0.2470023 0.0
            -0.2607247 -0.2607247 0.0
            -0.2744471 -0.2744471 0.0
            -0.2881694 -0.2881694 0.0
            -0.3018918 -0.3018918 0.0
            -0.3156141 -0.3156141 0.0
            -0.3293365 -0.3293365 0.0
            -0.3430588 -0.3430588 0.0
            -0.3567812 -0.3567812 0.0
            -0.3705035 -0.3705035 0.0
            -0.3842259 -0.3842259 0.0
            -0.3979482 -0.3979482 0.0
            -0.4116706 -0.4116706 0.0
            -0.4253929 -0.4253929 0.0
            -0.4391153 -0.4116706 0.0
            -0.4528376 -0.3979482 0.0
            -0.46656 -0.3842259 0.0
            -0.4802823 -0.3705035 0.0
            -0.4940047 -0.3567812 0.0
            -0.5077271 -0.3430588 0.0
            -0.5214494 -0.3293365 0.0
            -0.5351718 -0.3156141 0.0
            -0.5488941 -0.3018918 0.0
            -0.5626165 -0.2881694 0.0
            -0.5763388 -0.2744471 0.0
            -0.5900612 -0.2607247 0.0
            -0.6037835 -0.2470023 0.0
            -0.6175059 -0.23328 0.0
            -0.6312282 -0.2195576 0.0
            -0.6449506 -0.2058353 0.0
            -0.6586729 -0.1921129 0.0
            -0.6723953 -0.1783906 0.0
            -0.6861176 -0.1646682 0.0
            -0.69984 -0.1509459 -0.0
            -0.7135623 -0.1372235 0.0
            -0.7272847 -0.1235012 0.0
            -0.741007 -0.1097788 -0.0
            -0.7547294 -0.0960565 0.0
            -0.7684518 -0.0823341 0.0
            -0.7821741 -0.0686118 -0.0
            -0.7958965 -0.0548894 0.0
            -0.8096188 -0.0411671 0.0
            -0.8233412 -0.0274447 -0.0
            -0.8370635 -0.0137224 0.0
            -0.8507859 0.0 0.0
            -0.8314498 0.0 0.0
            -0.8121138 -0.0 -0.0
            -0.7927777 0.0 0.0
            -0.7734417 -0.0 0.0
            -0.7541057 0.0 0.0
            -0.7347696 0.0 0.0
            -0.7154336 0.0 0.0
            -0.6960975 -0.0 -0.0
            -0.6767615 -0.0 0.0
            -0.6574254 0.0 0.0
            -0.6380894 -0.0 0.0
            -0.6187534 0.0 -0.0
            -0.5994173 -0.0 -0.0
            -0.5800813 -0.0 0.0
            -0.5607452 0.0 0.0
            -0.5414092 0.0 0.0
            -0.5220731 0.0 0.0
            -0.5027371 -0.0 -0.0
            -0.4834011 -0.0 -0.0
            -0.464065 0.0 -0.0
            -0.444729 0.0 0.0
            -0.4253929 0.0 0.0
            -0.4060569 -0.0 -0.0
            -0.3867209 -0.0 0.0
            -0.3673848 0.0 0.0
            -0.3480488 0.0 0.0
            -0.3287127 0.0 0.0
            -0.3093767 0.0 -0.0
            -0.2900406 0.0 -0.0
            -0.2707046 0.0 0.0
            -0.2513686 -0.0 -0.0
            -0.2320325 -0.0 0.0
            -0.2126965 0.0 0.0
            -0.1933604 0.0 0.0
            -0.1740244 -0.0 -0.0
            -0.1546883 0.0 -0.0
            -0.1353523 0.0 0.0
            -0.1160163 -0.0 0.0
            -0.0966802 0.0 0.0
            -0.0773442 0.0 0.0
            -0.0580081 -0.0 0.0
            -0.0386721 -0.0 0.0
            -0.019336 0.0 0.0
            0.0 0.0 0.0
            0.0 0.0 -0.0193656
            0.0 0.0 -0.0387312
            0.0 0.0 -0.0580968
            0.0 0.0 -0.0774623
            0.0 0.0 -0.0968279
            0.0 0.0 -0.1161935
            -0.0 -0.0 -0.1355591
            0.0 0.0 -0.1549247
            -0.0 -0.0 -0.1742903
            0.0 0.0 -0.1936559
            -0.0 -0.0 -0.2130214
            0.0 0.0 -0.232387
            0.0 0.0 -0.2517526
            -0.0 -0.0 -0.2711182
            -0.0 -0.0 -0.2904838
            -0.0 -0.0 -0.3098494
            0.0 0.0 -0.329215
            0.0 0.0 -0.3485805
            -0.0 -0.0 -0.3679461
            -0.0 -0.0 -0.3873117
            -0.0 -0.0 -0.4066773
            0.0 0.0 -0.4260429
            0.0 0.0 -0.4454085
            -0.0 -0.0 -0.4647741
            -0.0 -0.0 -0.4841397
            -0.0 -0.0 -0.5035052
            0.0 0.0 -0.5228708
            0.0 0.0 -0.5422364
            -0.0 -0.0 -0.561602
            0.0 0.0 -0.5809676
            -0.0 -0.0 -0.6003332
            -0.0 -0.0 -0.6196988
            -0.0 -0.0 -0.6390643
            0.0 0.0 -0.6584299
            -0.0 -0.0 -0.6777955
            0.0 0.0 -0.6971611
            -0.0 -0.0 -0.7165267
            -0.0 -0.0 -0.7358923
            0.0 0.0 -0.7552579
            -0.0 -0.0 -0.7746234
            0.0 0.0 -0.793989
            -0.0 -0.0 -0.8133546
            0.0 0.0 -0.8327202
            0.0 0.0 -0.8520858
            -0.8507859 -0.0 -0.0470488
            -0.8507859 0.0 0.0
            -0.4253929 -0.4253929 0.0
            -0.4253929 -0.4253929 -0.0195464
            -0.4253929 -0.4253929 -0.0390928
            -0.4253929 -0.4253929 -0.0586392
            -0.4253929 -0.4253929 -0.0781856
            -0.4253929 -0.4253929 -0.097732
            -0.4253929 -0.4253929 -0.1172784
            -0.4253929 -0.4253929 -0.1368248
            -0.4253929 -0.4253929 -0.1563712
            -0.4253929 -0.4253929 -0.1759176
            -0.4253929 -0.4253929 -0.1954641
            -0.4253929 -0.4253929 -0.2150105
            -0.4253929 -0.4253929 -0.2345569
            -0.4253929 -0.4253929 -0.2541033
            -0.4253929 -0.4253929 -0.2736497
            -0.4253929 -0.4253929 -0.2931961
            -0.4253929 -0.4253929 -0.3127425
            -0.4253929 -0.4253929 -0.3322889
            -0.4253929 -0.4253929 -0.3518353
            -0.4253929 -0.4253929 -0.3713817
            -0.4253929 -0.4253929 -0.3909281
            -0.4253929 -0.4253929 -0.4104745
            -0.4253929 -0.4253929 -0.4300209
            -0.4253929 -0.4253929 -0.4495673
            -0.4253929 -0.4051361 -0.4495673
            -0.4253929 -0.3848793 -0.4495673
            -0.4253929 -0.3646225 -0.4495673
            -0.4253929 -0.3443657 -0.4495673
            -0.4253929 -0.3241089 -0.4495673
            -0.4253929 -0.3038521 -0.4495673
            -0.4253929 -0.2835953 -0.4495673
            -0.4253929 -0.2633385 -0.4495673
            -0.4253929 -0.2430817 -0.4495673
            -0.4253929 -0.2228249 -0.4495673
            -0.4253929 -0.2025681 -0.4495673
            -0.4253929 -0.1823113 -0.4495673
            -0.4253929 -0.1620545 -0.4495673
            -0.4253929 -0.1417976 -0.4495673
            -0.4253929 -0.1215408 -0.4495673
            -0.4253929 -0.101284 -0.4495673
            -0.4253929 -0.0810272 -0.4495673
            -0.4253929 -0.0607704 -0.4495673
            -0.4253929 -0.0405136 -0.4495673
            -0.4253929 -0.0202568 -0.4495673
            -0.4253929 -0.0 -0.4495673
            -0.4120994 -0.0 -0.4355183
            -0.3988059 -0.0 -0.4214694
            -0.3855123 -0.0 -0.4074204
            -0.3722188 -0.0 -0.3933714
            -0.3589253 -0.0 -0.3793224
            -0.3456318 -0.0 -0.3652734
            -0.3323382 -0.0 -0.3512245
            -0.3190447 -0.0 -0.3371755
            -0.3057512 -0.0 -0.3231265
            -0.2924576 -0.0 -0.3090775
            -0.2791641 -0.0 -0.2950286
            -0.2658706 -0.0 -0.2809796
            -0.2525771 -0.0 -0.2669306
            -0.2392835 -0.0 -0.2528816
            -0.22599 -0.0 -0.2388326
            -0.2126965 -0.0 -0.2247837
            -0.1994029 -0.0 -0.2107347
            -0.1861094 -0.0 -0.1966857
            -0.1728159 -0.0 -0.1826367
            -0.1595224 -0.0 -0.1685877
            -0.1462288 -0.0 -0.1545388
            -0.1329353 -0.0 -0.1404898
            -0.1196418 -0.0 -0.1264408
            -0.1063482 -0.0 -0.1123918
            -0.0930547 -0.0 -0.0983429
            -0.0797612 -0.0 -0.0842939
            -0.0664676 -0.0 -0.0702449
            -0.0531741 -0.0 -0.0561959
            -0.0398806 -0.0 -0.0421469
            -0.0265871 -0.0 -0.028098
            -0.0132935 -0.0 -0.014049
            0.0 0.0 0.0
        ]' * u"bohr^-1"
    f2c = CartesianFromFractional(reci_lattice)
    @test maximum(abs.(f2c(qe_crystal) - qe_cartesian)) < 1e-5u"bohr^-1"
end


"""
    ComplexD64

A complex value formed or Double64 real and imaginary parts
Also a constructor for that.
"""

struct ComplexD64 <: Number
    hilo::Tuple{Complex{Float64}, Complex{Float64}}
end

ComplexD64(x::ComplexD64) = x
ComplexD64(x::Double64) = ComplexD64((x, ZeroD64))
ComplexD64(x::Float64) = ComplexD64((Double64(x), ZeroD64)))

function ComplexD64(hi::Complex{Float64}, lo::Complex{Float64})
    rehi, relo = two_sum(real(hi), real(lo))
    imhi, imlo = two_sum(imag(hi), imag(lo))
    hi = ComplexF64(rehi, imhi)
    lo = ComplexF64(relo, imlo)
    ComplexD64((hi, lo))
end

function ComplexD64(real::Double64, imag::Double64)
    rehi, relo = HiLo(real)
    imhi, imlo = HiLo(imag)
     hi = ComplexF64(rehi, imhi)
    lo = ComplexF64(relo, imlo)
    ComplexD64((hi, lo))
end

Hi(x::ComplexD64) = x.hilo[1]
Lo(x::ComplexD64) = x.hilo[2]
HiLo(x::ComplexD64) = x.hilo

Base.real(x::ComplexD64) = Double64(real(hi(x)), real(lo(x)))
Base.imag(x::ComplexD64) = Double64(imag(hi(x)), imag(lo(x)))

ComplexD64(real::Double64, imag::Double64) =
    ComplexD64(Complex{Float64}(Hi(real), Hi(imag)), Complex(Float64(Lo(real), Lo(imag)))

const CplxD64 = Complex{Double64}

Hi(x::ComplexD64) = ComplexF64(Hi(x.re), Hi(x.im))
Lo(x::ComplexD64) = ComplexF64(Lo(x.re), Lo(x.im))
HiLo(x::ComplexD64) = Hi(x), Lo(x)

"""
    FloatComplexD64 <: Union
Union of Double64 and ComplexD64 types.
"""
const FloatComplexD64 = Union{Double64, ComplexD64}

Base.real(x::Double64) = x
Base.imag(x::Double64) = Double64((0.0, 0.0))


module NuclearRepulsion

using TypesParticles

export calcnuclrepul

"""
    Use: calcnuclrepul(system:SystemOfAtoms)

Input:
Results:

Description: returns the total energy from the nuclear-nuclear repulsion. This is a direct
sum calculation, as opposed to Ewald summation or particle mesh solvers.

TODO: return energy in units of eV or Ha

""" function calcnuclrepul(system::SystemOfAtoms)
    energy = 0.00e0;
    if system.natoms == 1
        return energy
    else
        for i=1:system.natoms
            atomi = system.atoms[i]
            for j=i+1:system.natoms;
                atomj = system.atoms[j];
                mag_rij = sqrt((atomj.x-atomi.x)^2 +
                              (atomj.y-atomi.y)^2 +
                              (atomj.z-atomi.z)^2);
                energy = energy + atomi.Z*atomj.Z/mag_rij;
            end
        end #system.natoms
        return energy
    end
end #get_nucl_nucl

end #NuclearRepulsion


using Revise
using Dice
using Dice: num_flips, num_nodes

# Convert (value, weight) tuples to input for dice discrete distribution
# Example: unpack_sparse([(0, 0.2), (3, 0.8)]) => [0.2, 0.0, 0.0, 0.8]
function unpack_sparse(sparse::Vector{Tuple{Int,Float64}})
    dice_disc = zeros(maximum(val for (val, _) in sparse) + 1)
    for (val, weight) in sparse
        dice_disc[val + 1] = weight
    end
    return dice_disc
end

# Generate Dice code for P[X+Y = res] given distributions of X and Y
function gen_code1(
    sparse1::Vector{Tuple{Int,Float64}},
    sparse2::Vector{Tuple{Int,Float64}}
)
    discrete_dist1 = unpack_sparse(sparse1)
    discrete_dist2 = unpack_sparse(sparse2)
    @dice begin
        function discrete(p::Vector{Float64})
            mb = length(p)
            v = Vector(undef, mb)
            sum = 1
            for i=1:mb
                v[i] = p[i]/sum
                sum = sum - p[i]
            end

            ans = DistInt(dicecontext(), mb-1)
            for i=mb-1:-1:1
                ans = if flip(v[i]) DistInt(dicecontext(), i-1) else ans end
            end
            return ans
        end

        a = add_bits(discrete(discrete_dist1), 1)
        b = add_bits(discrete(discrete_dist2), 1)
        (a + b)[1]
    end
end

# Generate Dice code for P[X+Y = res] given distributions of X and Y
function gen_code2(
    sparse1::Vector{Tuple{Int,Float64}},
    sparse2::Vector{Tuple{Int,Float64}}
)
    @dice begin
        function discrete_from_sparse(sparse::Vector{Tuple{Int,Float64}})
            v = Dict()
            sum = 1.
            for (val, weight) in sparse
                v[val] = weight/sum
                sum -= weight
            end

            ans = DistInt(dicecontext(), last(sparse)[1])
            for i = (length(sparse) - 1):-1:1
                (val, weight) = sparse[i]
                ans = if flip(v[val]) DistInt(dicecontext(), val) else ans end
            end
            return ans
        end

        a = add_bits(discrete_from_sparse(sparse1), 1)
        b = add_bits(discrete_from_sparse(sparse2), 1)
        (a + b)[1]
    end
end

sparse1 = [(4, 0.3), (6, 0.2), (600, 0.5)] # 4 has probability 0.3, etc...
sparse2 = [(0, 0.2), (4, 0.3), (9, 0.5)]
total_time1 = 0.
total_time2 = 0.

code = gen_code1(sparse1, sparse2)
bdd = compile(code)
println("Using a \"dense\" discrete function (original):")
println(num_nodes(bdd), " nodes")
println(num_flips(bdd), " flips")
@time one_res = infer(code, :bdd)

code = gen_code2(sparse1, sparse2)
bdd = compile(code)
println("Using a \"sparse\" discrete function:")
println(num_nodes(bdd), " nodes")
println(num_flips(bdd), " flips")
@time two_res = infer(code, :bdd)

# This check is stricter than need be. If fails, consider switching to isapprox
@assert one_res == two_res


using CoordinateSystems
using Base.Test
using ImmutableArrays

# write your own tests here
@test CoordinateSystems.normalize(Vector3(2.0,0.0,0.0)) == Vector3(1.0,0.0,0.0)

v0 = Vector3(0.0,0.0,0.0)
vx = Vector3(1.0,0.0,0.0)
vy = Vector3(0.0,1.0,0.0)
vz = Vector3(0.0,0.0,1.0)
vn = Vector3(1.0,2.0,3.0)

normal_cs = CoordinateSystem(v0,vz,vx)
@test to_global(normal_cs,vn) == vn
@test from_global(normal_cs,vn) == vn

flipxy_cs = CoordinateSystem(v0,vz,vy)
@test to_global(flipxy_cs,vn) == Vector3(-2.0,1.0,3.0)
@test from_global(flipxy_cs,vn) == Vector3(2.0,-1.0,3.0)

offsetx_cs = CoordinateSystem(vx,vx+vz,vx+vx)
@test to_global(offsetx_cs,vn) == Vector3(2.0,2.0,3.0)
@test from_global(offsetx_cs,vn) == Vector3(0.0,2.0,3.0)


# ================ Plotting 2D =================== #
using PyPlot
fig = figure()
ax = fig["add_subplot"](111, projection="3d")
stress_y =  200.0

function vm_upper(a, c)
    vals = f(a[1], a[2], c)
    vm(vals[1], vals[2], 200)
end
vm(a,b) = sqrt(a^2 - a*b + b^2) - stress_y
f(m,c) = [600*cos(c) 600*sin(c)].*m
x_vals = []
max_iter = 100
y_vals = []
for i=0:0.1:(2*pi+0.3)
    wf(x) = f(x, i)
    t = 0.01
    step = 2
    merkki = -1
    s11, s22 = wf(t)
    ii = 0
    while (abs(vm(s11, s22)) > 1e-7) && ii < max_iter
        val = vm(s11, s22)
        if sign(val) != merkki
            merkki *= -1
            step *= -0.5
        end
        t += step
        s11, s22 = wf(t)
        ii += 1
    end
    push!(x_vals, s11)
    push!(y_vals, s22)
end

#plot(x_vals, y_vals)
#PyPlot.title("von Mises yield surface in 2D")
#PyPlot.xlabel("Eig Stress 1")
#PyPlot.ylabel("Eig Stress 2")
#grid()
#show()

# ================ Plotting 3D =================== #
n(θ, ϕ) = [sin(θ)*cos(ϕ)
           sin(θ)*sin(ϕ)
           cos(θ)]

m(θ, ϕ, χ) = [-sin(ϕ)*cos(χ)-cos(θ)*cos(ϕ)*sin(χ)
               cos(ϕ)*cos(χ)-cos(θ)*sin(ϕ)*sin(χ)
               sin(θ)*sin(χ)]

w = [sqrt(2/3) * 200 * m(54.735 * pi / 180, 45 * pi/180, x) for x=0:0.15:(2*pi+0.1)]
base_vec =  [1 1 1] / sqrt(3)

for i=-5:5
    tt = [w[x] + vec(base_vec) + 50 * i for x=1:length(w)]
    x = map(x->tt[x][1], collect(1:length(w)))
    y = map(x->tt[x][2], collect(1:length(w)))
    z = map(x->tt[x][3], collect(1:length(w)))
    plot3D(x, y, z, color="blue")
end

tt = [w[x] + vec(base_vec) + 50 * -5 for x=1:length(w)]
x_start = map(x->tt[x][1], collect(1:length(w)))[1:5:end]
y_start = map(x->tt[x][2], collect(1:length(w)))[1:5:end]
z_start = map(x->tt[x][3], collect(1:length(w)))[1:5:end]

tt = [w[x] + vec(base_vec) + 50 * 5 for x=1:length(w)]
x_end = map(x->tt[x][1], collect(1:length(w)))[1:5:end]
y_end = map(x->tt[x][2], collect(1:length(w)))[1:5:end]
z_end = map(x->tt[x][3], collect(1:length(w)))[1:5:end]

for i=1:length(x_start)
    x = [x_start[i], x_end[i]]
    y = [y_start[i], y_end[i]]
    z = [z_start[i], z_end[i]]
    plot3D(x, y, z, color="blue")
end

info("Calculation finished")

# plot the surface
xx = zeros(10, 10)
yy = zeros(10, 10)

for i=1:10
    for j=1:10
        xx[i, j] = (i - 5) * 100
        yy[i, j] = (j - 5) * 100
    end
end

# calculate corresponding z
z = zeros(10, 10)
for i=1:10
    for j=1:10
        z[i, j] = 1
    end
end

# plot the surface
plot_surface(xx, yy, z, color="blue")
plot(x_vals, y_vals, zeros(length(y_vals)), color="yellow")
axis("equal")
PyPlot.title("von Mises yield surface in 3D")
PyPlot.xlabel("Eig Stress 1")
PyPlot.ylabel("Eig Stress 2")
PyPlot.zlabel("Eig Stress 3")
for i=1:360
    ax["view_init"](30, i)
    PyPlot.draw()
    savefig("$(lpad(i, 3, 0))_plot.png")
end


# Parts of this code were taken / derived from Graphs.jl. See LICENSE for
# licensing details.

#################################################
#
#  Minimum Cut
#
#################################################

"""
    mincut(g, distmx=weights(g))

Return a tuple `(parity, bestcut)`, where `parity` is a vector of integer
values that determines the partition in `g` (1 or 2) and `bestcut` is the
weight of the cut that makes this partition. An optional `distmx` matrix may
be specified; if omitted, edge distances are assumed to be 1.
"""
function mincut(g::AbstractGraph,
    distmx::AbstractMatrix{T}=weights(g)) where T <: Real

    U = eltype(g)
    colormap = zeros(UInt8, nv(g))   ## 0 if unseen, 1 if processing and 2 if seen and closed
    parities = falses(nv(g))
    bestweight = typemax(T)
    cutweight = zero(T)
    visited = zero(U)               ## number of vertices visited
    pq = PriorityQueue{U,T}(Base.Order.Reverse)

    # Set number of visited neighbors for all vertices to 0
    for v in vertices(g)
        pq[v] = zero(T)
    end

    # make sure we have at least two vertices, otherwise, there's nothing to cut,
    # in which case we'll return immediately.
    (haskey(pq, one(U)) && nv(g) > one(U)) || return (Vector{Int8}([1]), cutweight)

    #Give the starting vertex high priority
    pq[one(U)] = one(T)

    while !isempty(pq)
        u = dequeue!(pq)
        colormap[u] = 1

        for v in outneighbors(g, u)
            # if the target of e is already marked then decrease cutweight
            # otherwise, increase it
            ew = distmx[u, v]
            if colormap[v] != 0
                cutweight -= ew
            else
                cutweight += ew
            end
            if haskey(pq, v)
                pq[v] += distmx[u, v]
            end
        end

        colormap[u] = 2
        visited += one(U)
        if cutweight < bestweight && visited < nv(g)
            bestweight = cutweight
            for u in vertices(g)
                parities[u] = (colormap[u] == 2)
            end
        end
    end
    return(convert(Vector{Int8}, parities) .+ one(Int8), bestweight)
end

"""
    maximum_adjacency_visit(g[, distmx][, log][, io])

Return the vertices in `g` traversed by maximum adjacency search. An optional
`distmx` matrix may be specified; if omitted, edge distances are assumed to
be 1. If `log` (default `false`) is `true`, visitor events will be printed to
`io`, which defaults to `STDOUT`; otherwise, no event information will be
displayed.
"""
function maximum_adjacency_visit(g::AbstractGraph,
    distmx::AbstractMatrix{T},
    log::Bool=false,
    io::IO=stdout) where T <: Real

    U = eltype(g)
    pq = PriorityQueue{U,T}(Base.Order.Reverse)
    vertices_order = Vector{U}()
    has_key = ones(Bool, nv(g))
    sizehint!(vertices_order, nv(g))
    # if the graph only has one vertex, we return the vertex by itself.
    nv(g) > one(U) || return collect(vertices(g))

    # Setting intial count to 0
    for v in vertices(g)
        pq[v] = zero(T)
    end

    #Give vertex `1` maximum priority
    pq[one(U)] = one(T)

    #start traversing the graph
    while !isempty(pq)
        u = dequeue!(pq)
        has_key[u] = false
        push!(vertices_order, u)
        log && println(io, "discover vertex: $u")
        for v in outneighbors(g, u)
            log && println(io, " -- examine neighbor from $u to $v")
            if has_key[v]
                ed = distmx[u, v]
                pq[v] += ed
            end
        end
        log && println(io, "close vertex: $u")
    end
    return vertices_order
end

maximum_adjacency_visit(g::AbstractGraph) = maximum_adjacency_visit(g,
    weights(g),
    false,
    stdout)


using Symbolics
using Symbolics: hasdiff
using Test

@variables t x
D1 = Difference(t; dt=0.01)
D2 = Difference(t; dt=0.01)

@test D1 == D2
@test Base.isequal(D1, D2)
@test Base.hash(D1) == Base.hash(D2)

@test D1(x) isa Num

@test isequal((D1^2)(x), D1(D1(x)))

# hasdiff
@test hasdiff(D1)
@test hasdiff(D1(x) ~ x)
@test hasdiff(x ~ D1(x))
@test !hasdiff(t ~ x)
@test hasdiff((D1^2)(x) ~ x)
@test hasdiff(D1(x) ~ D2(x))