Skip to content

Commit 708afbe

Browse files
committed
Detect supercell interpenetration in dimensionality
1 parent d520aea commit 708afbe

File tree

4 files changed

+52
-24
lines changed

4 files changed

+52
-24
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PeriodicGraphs"
22
uuid = "18c5b727-b240-4874-878a-f2e242435bab"
33
authors = ["Lionel Zoubritzky [email protected]"]
4-
version = "0.9.6"
4+
version = "0.10.0"
55

66
[deps]
77
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3-
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
43
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
4+
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
55

66
[compat]
77
Documenter = "0.27"

src/algorithms/dimensionality.jl

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ Given a list of integer vectors of dimension `N`, return a tuple `(mat, D)` wher
127127
invertible matrix whose `D` first columns form a basis of this spanned space, which
128128
does not depend on the exact input.
129129
130-
If `D ≠ N`, the remaining columns are set so that `mat` be invertible. Nothing
131-
else is specified about these columns, and in particular you should not assume that
132-
they are independent of the input.
130+
If `D ≠ N`, the remaining columns are set so that `mat` be invertible. These additional
131+
columns will only contain one coefficient equal to 1, and all others to 0. No other
132+
assumption should be made about these columns; in particular, they may depend on the input.
133133
134134
!!! warning
135135
If modifiable, the input list will be modified in-place during this process.
@@ -236,14 +236,37 @@ end
236236
dimensionality(g::PeriodicGraph{N}) where N
237237
238238
Determine the actual dimension of each connected component of `g`.
239-
Return a dictionary where each entry `n => [l1, l2, ...]` means that
240-
`li` is a list of vertices that form a connected component of dimension `n`.
239+
Return a dictionary where each entry `n => [(l1,m1), (l2,m2), ...]` means that
240+
`li` is a list of vertices that form a connected component of dimension `n`, and that
241+
component is present `mi` times per unit cell.
242+
243+
In other words, the connected component `li` has a periodicity that can only be expressed
244+
in a unit cell `mi` times larger than the current one.
245+
246+
## Examples
247+
```jldoctest
248+
julia> dimensionality(PeriodicGraph("2 1 1 1 0 2 2 -1 1 3 3 1 0 3 3 0 1"))
249+
Dict{Int64, Vector{Tuple{Vector{Int64}, Int64}}} with 2 entries:
250+
2 => [([3], 1)]
251+
1 => [([1], 1), ([2], 1)]
252+
253+
julia> dimensionality(PeriodicGraph("1 1 1 2"))
254+
Dict{Int64, Vector{Tuple{Vector{Int64}, Int64}}} with 1 entry:
255+
1 => [([1], 2)]
256+
```
241257
"""
242258
function dimensionality(g::PeriodicGraph)
243259
dim = _dimensionality(g)
244-
ret = Dict{Int,Vector{Vector{Int}}}()
260+
ret = Dict{Int,Vector{Tuple{Vector{Int},Int}}}()
245261
@inbounds for (d, x) in dim
246-
ret[d] = first.(x)
262+
retd = Vector{Tuple{Vector{Int},Int}}(undef, length(x))
263+
for (k, (l, vec)) in enumerate(x)
264+
nfoldmat, d2 = normal_basis(vec)
265+
@assert d2 == d
266+
nfold = abs(det(nfoldmat))
267+
retd[k] = (l, nfold)
268+
end
269+
ret[d] = retd
247270
end
248271
return ret
249272
end

test/runtests.jl

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -679,37 +679,42 @@ end
679679
@test g2 == gref
680680
end
681681

682-
function equivalent_dict(d1, d2)
682+
function check_dimensionality(g, d2)
683+
d1 = dimensionality(g)
683684
keys(d1) == keys(d2) || return false
684685
for k in keys(d1)
685-
s1 = Set(Set(x) for x in d1[k])
686-
s2 = Set(Set(x) for x in d2[k])
686+
s1 = Set((Set(l), m) for (l,m) in d1[k])
687+
s2 = Set((Set(l), m) for (l,m) in d2[k])
687688
s1 == s2 || return false
688689
end
689690
return true
690691
end
691692

692693
@testset "Dimensionality" begin
693-
@test dimensionality(PeriodicGraph{0}(5)) == Dict(0 => [collect(1:5)])
694+
@test dimensionality(PeriodicGraph{0}(5)) == Dict(0 => [(collect(1:5),1)])
694695
g::PeriodicGraph3D = PeriodicGraph3D([PeriodicEdge3D(1, 3, (0, 0, 1)),
695696
PeriodicEdge3D(2, 3, (0, 1, 0)),
696-
PeriodicEdge3D(2, 3, (0, -1, 0)),
697+
PeriodicEdge3D(2, 3, (0, 0, 0)),
697698
PeriodicEdge3D(4, 4, (1, 1, 0))])
698-
@test equivalent_dict(dimensionality(g), Dict(1 => connected_components(g)))
699-
@test add_edge!(g, PeriodicEdge(3, 2, (0,0,0)))
700-
@test equivalent_dict(dimensionality(g), Dict(1 => connected_components(g)))
699+
@test check_dimensionality(g, Dict(1 => [(x,1) for x in connected_components(g)]))
700+
@test add_edge!(g, PeriodicEdge(2, 3, (0,-1,0)))
701+
@test check_dimensionality(g, Dict(1 => [(x,1) for x in connected_components(g)]))
701702
@test add_edge!(g, PeriodicEdge(2, 2, (0,0,1)))
702-
@test equivalent_dict(dimensionality(g), Dict(1 => [[4]], 2 => [[1,2,3]]))
703+
@test check_dimensionality(g, Dict(1 => [([4],1)], 2 => [([1,2,3],1)]))
703704
@test rem_edge!(g, PeriodicEdge(1, 3, (0,0,1)))
704-
@test equivalent_dict(dimensionality(g), Dict(0 => [[1]], 1 => [[4]], 2 => [[2,3]]))
705+
@test check_dimensionality(g, Dict(0 => [([1],1)], 1 => [([4],1)], 2 => [([2,3],1)]))
705706
@test rem_edge!(g, 3, PeriodicVertex(2, (0,0,0)))
706-
@test equivalent_dict(dimensionality(g), Dict(0 => [[1]], 1 => [[4]], 2 => [[2,3]]))
707+
@test check_dimensionality(g, Dict(0 => [([1],1)], 1 => [([4],1)], 2 => [([2,3],2)]))
707708
@test rem_edge!(g, PeriodicEdge(2, 3, (0,1,0)))
708-
@test equivalent_dict(dimensionality(g), Dict(0 => [[1]], 1 => [[2,3],[4]]))
709+
@test check_dimensionality(g, Dict(0 => [([1],1)], 1 => [([2,3],1),([4],1)]))
709710
@test add_edge!(g, 2, PeriodicVertex3D(3, (1,0,-1)))
710-
@test equivalent_dict(dimensionality(g), Dict(0 => [[1]], 1 => [[4]], 2 => [[2,3]]))
711+
@test check_dimensionality(g, Dict(0 => [([1],1)], 1 => [([4],1)], 2 => [([2,3],1)]))
711712
@test add_edge!(g, 2, PeriodicVertex(3, (2,0,-1)))
712-
@test equivalent_dict(dimensionality(g), Dict(0 => [[1]], 1 => [[4]], 3 => [[2,3]]))
713+
@test check_dimensionality(g, Dict(0 => [([1],1)], 1 => [([4],1)], 3 => [([2,3],1)]))
714+
715+
@test check_dimensionality(PeriodicGraph("2 1 1 2 0 1 1 0 1"), Dict(2 => [([1],2)]))
716+
@test check_dimensionality(PeriodicGraph("3 1 1 2 0 0 1 1 0 2 0"), Dict(2 => [([1],4)]))
717+
@test check_dimensionality(PeriodicGraph("3 1 1 0 0 1 1 2 -1 0 0 1 2 0 -1 0 1 2 1 0 0"), Dict(3 => [([1,2],2)]))
713718
end
714719

715720
@testset "Dimension change" begin
@@ -719,7 +724,7 @@ end
719724
3 4 -1 0 0
720725
4 1 0 0 1
721726
4 4 0 0 1")
722-
@test equivalent_dict(dimensionality(g), Dict(1 => [[1,2,3,4]]))
727+
@test check_dimensionality(g, Dict(1 => [(1:4,1)]))
723728
gg = PeriodicGraph1D(g)
724729
@test string(gg) == "1 1 2 0 1 4 -1 2 3 0 3 4 0 4 4 1"
725730
@test PeriodicGraph2D(gg) == PeriodicGraph2D(g) ==

0 commit comments

Comments
 (0)