forked from JuliaMolSim/DFTK.jl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bzmesh.jl
149 lines (125 loc) · 5.86 KB
/
bzmesh.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
@testitem "MonkhorstPack reducible_kcoords agrees with spglib" begin
using DFTK: normalize_kpoint_coordinate
using DFTK
using Spglib
using LinearAlgebra
function test_against_spglib(kgrid_size; kshift=[0, 0, 0])
kgrid_size = Vec3(kgrid_size)
is_shift = ifelse.(kshift .== 0, false, true)
diagonal = Matrix{Int64}(I, 3, 3)
spg_mesh = Spglib.get_stabilized_reciprocal_mesh([diagonal], kgrid_size;
is_shift, is_time_reversal=false)
kcoords_spglib = normalize_kpoint_coordinate.(Spglib.eachpoint(spg_mesh))
sort!(kcoords_spglib)
(; kcoords) = DFTK.reducible_kcoords(MonkhorstPack(kgrid_size, kshift))
@test sort!(kcoords) == kcoords_spglib
end
test_against_spglib([ 2, 3, 2])
test_against_spglib([ 3, 3, 3])
test_against_spglib([ 3, 3, 3], kshift=[1//2, 0, 0])
test_against_spglib([ 2, 3, 4])
test_against_spglib([ 9, 11, 13])
end
# PythonCall does not play nicely with MPI.
@testitem "MonkhorstPack irreducible_kcoords is correct reduction" #=
=# tags=[:dont_test_mpi] setup=[TestCases] begin
using Logging
using AtomsBuilder
(; silicon, magnesium, platinum_hcp) = TestCases.all_testcases
function test_reduction(testcase, kgrid_size, kirredsize;
supercell=(1, 1, 1), kshift=[0, 0, 0])
system = atomic_system(testcase.lattice, testcase.atoms, testcase.positions)
if supercell != (1, 1, 1) # Make supercell
system = system * supercell
end
kgrid = MonkhorstPack(kgrid_size, kshift)
symmetries = symmetry_operations(system)
sym_preserving_grid = DFTK.symmetries_preserving_kgrid(symmetries, kgrid)
red_kcoords = DFTK.reducible_kcoords(kgrid).kcoords
irred_kcoords = DFTK.irreducible_kcoords(kgrid, sym_preserving_grid).kcoords
@test length(irred_kcoords) == kirredsize
# Try to reproduce all kcoords from irred_kcoords
all_kcoords = Vector{Vec3{Rational{Int}}}()
for k in irred_kcoords
append!(all_kcoords, [symop.S * k for symop in sym_preserving_grid])
end
# Normalize the obtained k-points and test for equality
red_kcoords = unique(sort([mod.(k .* kgrid_size, kgrid_size) for k in red_kcoords]))
all_kcoords = unique(sort([mod.(k .* kgrid_size, kgrid_size) for k in all_kcoords]))
@test all_kcoords == red_kcoords
end
test_reduction(silicon, [ 2, 3, 2], 6)
test_reduction(silicon, [ 3, 3, 3], 4)
test_reduction(silicon, [ 2, 3, 4], 14)
test_reduction(silicon, [ 9, 11, 13], 644)
test_reduction(silicon, [ 3, 3, 3], 6, kshift=[1//2, 1//2, 1//2])
test_reduction(silicon, [ 3, 3, 3], 6, kshift=[1//2, 0, 1//2])
test_reduction(silicon, [ 3, 3, 3], 6, kshift=[0, 1//2, 0])
test_reduction(silicon, [ 1, 4, 4], 7, supercell=(2, 1, 1))
test_reduction(silicon, [ 1, 16, 16], 73, supercell=(4, 1, 1))
test_reduction(magnesium, [ 2, 3, 2], 8)
test_reduction(magnesium, [ 3, 3, 3], 6)
test_reduction(magnesium, [ 2, 3, 4], 12)
test_reduction(magnesium, [ 9, 11, 13], 350)
test_reduction(platinum_hcp, [5, 5, 5], 63)
end
@testitem "standardize_atoms" setup=[TestCases] begin
silicon = TestCases.silicon
# Test unperturbed structure
std = standardize_atoms(silicon.lattice, silicon.atoms, silicon.positions, primitive=true)
@test length(std.atoms) == 2
@test std.atoms[1].symbol == :Si
@test std.atoms[2].symbol == :Si
@test length(std.positions) == 2
@test std.positions[1] - std.positions[2] ≈ 0.25ones(3)
@test std.lattice ≈ silicon.lattice
# Perturb structure
plattice = silicon.lattice .+ 1e-8rand(3, 3)
patoms = silicon.atoms
ppositions = [p + 1e-8rand(3) for p in silicon.positions]
std = standardize_atoms(plattice, patoms, ppositions, primitive=true)
# And check we get the usual silicon primitive cell back:
a = std.lattice[1, 2]
@test std.lattice == [0 a a; a 0 a; a a 0]
@test length(std.atoms) == 2
@test std.atoms[1].symbol == :Si
@test std.atoms[2].symbol == :Si
@test length(std.positions) == 2
@test std.positions[1] - std.positions[2] ≈ 0.25ones(3)
end
@testitem "kgrid_from_maximal_spacing" setup=[TestCases] begin
using DFTK
using Unitful
@testset "Simple lattice with units" begin
# Test that units are stripped from both the lattice and the spacing
lattice = [[-1.0 1 1]; [1 -1 1]; [1 1 -1]]
@test kgrid_from_maximal_spacing(lattice * u"Å", 0.5 / u"Å").kgrid_size == [9, 9, 9]
end
@testset "Magnesium system" begin
magnesium = TestCases.magnesium
system = periodic_system(magnesium.lattice, magnesium.atoms, magnesium.positions)
@test kgrid_from_maximal_spacing(system, 0.5 / u"Å").kgrid_size == [5, 5, 3]
end
end
@testitem "kgrid_from_minimal_n_kpoints" setup=[TestCases] begin
using DFTK
using Unitful
using LinearAlgebra
@testset "Simple lattice with units" begin
lattice = [[-1.0 1 1]; [1 -1 1]; [1 1 -1]]
@test kgrid_from_minimal_n_kpoints(lattice * u"Å", 1000).kgrid_size == [10, 10, 10]
end
@testset "Magnesium system" begin
magnesium = TestCases.magnesium
system = periodic_system(magnesium.lattice, magnesium.atoms, magnesium.positions)
@test kgrid_from_minimal_n_kpoints(system, 1).kgrid_size == [1, 1, 1]
for n_kpt in [10, 20, 100, 400, 900, 1200]
@test length(kgrid_from_minimal_n_kpoints(system, n_kpt)) ≥ n_kpt
end
end
@testset "Reduced dimension" begin
lattice = diagm([4., 10, 0])
@test kgrid_from_minimal_n_kpoints(lattice, 1000).kgrid_size == [50, 20, 1]
@test kgrid_from_minimal_n_kpoints(diagm([10, 0, 0]), 913).kgrid_size == [913, 1, 1]
end
end