Skip to content

Commit 0ef8b75

Browse files
committed
Merge branch 'master' into bandpaths-data
2 parents 041d4ac + 3a2164a commit 0ef8b75

File tree

969 files changed

+70281
-506
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

969 files changed

+70281
-506
lines changed

Bravais/Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Bravais"
22
uuid = "ada6cbde-b013-4edf-aa94-f6abe8bd6e6b"
33
authors = ["Thomas Christensen <[email protected]>"]
4-
version = "0.1.8"
4+
version = "0.1.9"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

Bravais/src/Bravais.jl

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export crystal,
2323
bravaistype,
2424
centering,
2525
primitivebasismatrix,
26+
centering_volume_fraction,
2627
directbasis,
2728
reciprocalbasis,
2829
AbstractBasis,

Bravais/src/transform.jl

+38-33
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ function canonicalize_centering(cntr, ::Val{D}, ::Val{P}) where {D,P}
6969
if D == P # space/plane/line groups
7070
return cntr
7171
elseif D == 3 && P == 2 # layer groups
72-
return cntr == '𝑝' ? 'p' :
73-
cntr == '𝑐' ? 'c' : error(DomainError(cntr, "invalid layer group centering"))
72+
return cntr == '𝑝' ? 'P' :
73+
cntr == '𝑐' ? 'C' : error(DomainError(cntr, "invalid layer group centering"))
7474
elseif D == 3 && P == 1 # rod groups
75-
return cntr == '𝓅' ? 'p' : error(DomainError(cntr, "invalid rod group centering"))
75+
return cntr == '𝓅' ? 'P' : error(DomainError(cntr, "invalid rod group centering"))
7676
elseif D == 2 && P == 1 # frieze groups
7777
return cntr == '𝓅' ? 'p' : error(DomainError(cntr, "invalid frieze group centering"))
7878
else
@@ -161,38 +161,18 @@ frequently and more ambiguously, as the crystallographic primitive setting.
161161
Thus, Bravais.jl and [Spglib.jl](https://github.com/singularitti/Spglib.jl)
162162
transform to identical primitive settings and are hence mutually compatible.
163163
"""
164-
@inline function primitivebasismatrix(cntr::Char, ::Val{D}=Val(3), ::Val{D}=Val(D)) where D
165-
# space groups
164+
@inline function primitivebasismatrix(cntr::Char,
165+
Dᵛ::Val{D}=Val(3), Pᵛ::Val{P}=Val(D)) where {D,P}
166166
D 1:3 && _throw_invalid_dim(D)
167-
return PRIMITIVE_BASIS_MATRICES[D][cntr]
168-
end
169-
@inline function primitivebasismatrix(cntr::Char, Dᵛ::Val{3}, Pᵛ::Val{2})
170-
# layer and rod groups
167+
P 1:D && throw(DomainError((D,P), "invalid combination of dimensionality D and periodicity P"))
171168
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
172-
P²ᴰ = PRIMITIVE_BASIS_MATRICES[2][cntr]
173-
return @SMatrix [P²ᴰ[1,1] P²ᴰ[2,1] 0.0; P²ᴰ[1,2] P²ᴰ[2,2] 0.0; 0.0 0.0 1.0]
174-
end
175-
@inline function primitivebasismatrix(cntr::Char, Dᵛ::Val{3}, Pᵛ::Val{1})
176-
# rod groups
177-
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
178-
P²ᴰ = PRIMITIVE_BASIS_MATRICES[1][cntr]
179-
return @SMatrix [P²ᴰ[1,1] 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 1.0]
180-
end
181-
@inline function primitivebasismatrix(cntr::Char, Dᵛ::Val{2}, Pᵛ::Val{1})
182-
# frieze groups
183-
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
184-
P¹ᴰ = PRIMITIVE_BASIS_MATRICES[1][cntr]
185-
return @SMatrix [P¹ᴰ[1,1] 0.0; 0.0 1.0]
186-
end
187-
function primitivebasismatrix(cntr::Char, ::Val{D}, ::Val{P}) where {D,P}
188-
# fall-back error
189-
throw(DomainError((D,P), "invalid combination of dimensionality D and periodicity P"))
169+
return PRIMITIVE_BASIS_MATRICES[D][cntr]
190170
end
191171

192172
@inline function centeringtranslation(cntr::Char,
193173
Dᵛ::Val{D}=Val(3), Pᵛ::Val{P}=Val(D)) where {D,P}
194174
D 1:3 && _throw_invalid_dim(D)
195-
P 1:D && _throw_invalid_dim(P)
175+
P 1:D && throw(DomainError((D,P), "invalid combination of dimensionality D and periodicity P"))
196176
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
197177
if D == 3
198178
if cntr == 'P'; return zeros(SVector{3})
@@ -212,28 +192,53 @@ end
212192
if cntr == 'p'; return zeros(SVector{1})
213193
else; _throw_invalid_cntr(cntr, 1)
214194
end
215-
else
216-
_throw_invalid_dim(D)
217195
end
196+
error("unreachable reached")
218197
end
219198

220199
function all_centeringtranslations(cntr::Char,
221200
Dᵛ::Val{D}=Val(3), Pᵛ::Val{P}=Val(D)) where {D,P}
222201
D 1:3 && _throw_invalid_dim(D)
223202
P 1:D && _throw_invalid_dim(P)
224203
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
225-
if D == 3 && cntr == 'F'
204+
if cntr == 'P' || cntr == 'p'
205+
# primitive cell is equal to conventional cell: 0 extra centers
206+
return SVector{D,Float64}[]
207+
elseif D == 3 && cntr == 'F'
226208
# primitive cell has 1/4th the volume of conventional cell: 3 extra centers
227-
return [SVector((1,0,1)./2), SVector((0,1,1)./2), SVector((1,1,0)./2)]
209+
return [SVector((0,1,1)./2), SVector((1,0,1)./2), SVector((1,1,0)./2)]
228210
elseif D == 3 && cntr == 'R'
229211
# primitive cell has 1/3rd the volume of conventional cell: 2 extra centers
230212
return [SVector((2,1,1)./3), SVector((1,2,2)./3)]
231-
else
213+
else # 'I', 'C', 'c', 'A'
232214
# primitive cell has half the volume of conventional cell: 1 extra center
233215
return [centeringtranslation(cntr, Dᵛ)]
234216
end
235217
end
236218

219+
"""
220+
centering_volume_fraction(cntr, Dᵛ, Pᵛ) --> Int
221+
222+
Return the (integer-) ratio between the volumes of the conventional and primitive unit cells
223+
for a space or subperiodic group with centering `cntr`, embedding dimension `D`, and
224+
periodicity dimension `P`.
225+
"""
226+
@inline function centering_volume_fraction(cntr::Char,
227+
Dᵛ::Val{D}=Val(3), Pᵛ::Val{P}=Val(D)) where {D,P}
228+
D 1:3 && _throw_invalid_dim(D)
229+
P 1:D && _throw_invalid_dim(P)
230+
cntr = canonicalize_centering(cntr, Dᵛ, Pᵛ)
231+
if cntr == 'P' || cntr == 'p'
232+
return 1
233+
elseif D == 3 && cntr == 'F'
234+
return 4
235+
elseif D == 3 && cntr == 'R'
236+
return 3
237+
else # 'I', 'C', 'c', 'A'
238+
return 2
239+
end
240+
end
241+
237242
# ---------------------------------------------------------------------------------------- #
238243

239244
"""

Project.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Crystalline"
22
uuid = "ae5e2be0-a263-11e9-351e-f94dad1eb351"
33
authors = ["Thomas Christensen <[email protected]>"]
4-
version = "0.4.22"
4+
version = "0.5.0"
55

66
[deps]
77
Bravais = "ada6cbde-b013-4edf-aa94-f6abe8bd6e6b"
@@ -29,7 +29,7 @@ CrystallineGraphMakieExt = "GraphMakie"
2929
CrystallinePyPlotExt = "PyPlot"
3030

3131
[compat]
32-
Bravais = "0.1.8"
32+
Bravais = "0.1.9"
3333
Combinatorics = "1.0"
3434
DelimitedFiles = "1"
3535
DocStringExtensions = "0.8, 0.9"

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ CharacterTable{3}: ⋕16 (P222) at Γ = [0, 0, 0]
7171
──────┴────────────────
7272
```
7373

74-
Additional functionality includes e.g. point group operations (`pointgroup`) and irreps (`pgirreps`), elementary band representations (`bandreps`), Wyckoff positions (`wyckoffs`), conjugacy classes (`classes`), class-specific characters (`classcharacters`), group generators (`generators`), physically real irreps (`realify`), and Bravais lattice utilities and conventions (accessible via the lightweight stand-alone sub-package [Bravais.jl](https://github.com/thchr/Crystalline.jl/tree/master/Bravais)).
74+
Additional functionality includes e.g. point group operations (`pointgroup`) and irreps (`pgirreps`), elementary band representations (`bandreps`), Wyckoff positions (`wyckoffs`), conjugacy classes (`classes`), class-specific characters (`classcharacters`), group generators (`generators`), subperiodic groups (`subperiodicgroup`), 3D magnetic space groups (`mspacegroup`), and physically real irreps (`realify`).
75+
In addition, Bravais lattice utilities and conventions are accessible via the lightweight stand-alone sub-package [Bravais.jl](https://github.com/thchr/Crystalline.jl/tree/master/Bravais).
76+
7577
For a full description of the public API, see the [documentation][docs-dev-url].
7678

7779
### Current limitations

build/crawl_and_write_generators_pgs.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ let D = 3
5959
gens_str = crawl_pg_generators_xyzt(pgnum, D, pgiuc)
6060
end
6161

62-
unmangled_pgiuc = Crystalline.unmangle_pgiuclab(pgiuc)
62+
unmangled_pgiuc = Crystalline._unmangle_pgiuclab(pgiuc)
6363
filename = (@__DIR__)*"/../data/generators/pgs/$(D)d/$(unmangled_pgiuc).csv"
6464
open(filename; write=true, create=true, truncate=true) do io
6565
first = true
@@ -85,7 +85,7 @@ let D = 2
8585
for (pgnum, pgiuc) in enumerate(Crystalline.PG_IUCs[D])
8686
gens_str = crawl_pg_generators_xyzt(pgnum, D)
8787

88-
unmangled_pgiuc = Crystalline.unmangle_pgiuclab(pgiuc)
88+
unmangled_pgiuc = Crystalline._unmangle_pgiuclab(pgiuc)
8989
filename = (@__DIR__)*"/../data/generators/pgs/$(D)d/$(unmangled_pgiuc).csv"
9090
open(filename; write=true, create=true, truncate=true) do io
9191
first = true

build/crawl_and_write_pgs.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ function __crawl_and_write_3d_pgirreps()
180180

181181
# ==== save irreps ====
182182
# we do not save the point group operations anew; they are already stored in
183-
# "data/operations/pgs/..."; note that we explicitly checked the sorting and
184-
# equivalence of operations when pgirs was crawled above (cf. flag
183+
# "test/data/xyzt-operations/pgs/..."; note that we explicitly checked the
184+
# sorting and # equivalence of operations when pgirs was crawled above (cf. flag
185185
# `consistency_checks=true`)
186-
unmangled_pgiuc = Crystalline.unmangle_pgiuclab(pgiuc) # replace '/'s by '_slash_'s
186+
unmangled_pgiuc = Crystalline._unmangle_pgiuclab(pgiuc) # replace '/'s by '_slash_'s
187187
irreps_file[unmangled_pgiuc*"/matrices"] = matrices
188188
irreps_file[unmangled_pgiuc*"/realities"] = Integer.(realities)
189189
irreps_file[unmangled_pgiuc*"/cdmls"] = cdmls

build/crawl_and_write_subperiodic.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ end
5353

5454
# ---------------------------------------------------------------------------------------- #
5555
## Use crawling functions & write information to:
56-
# `/data/generators/subperiodic/{layer|rod|frieze}/`
57-
# `/data/operations/subperiodic/{layer|rod|frieze}/`
56+
# `/test/data/xyzt-operations/generators/subperiodic/{layer|rod|frieze}/`
57+
# `/test/data/xyzt-operations/subperiodic/{layer|rod|frieze}/`
5858
for (D, P, sub, maxnum) in [(3,2,"layer",80), (3,1,"rod",75), (2,1,"frieze",7)]
5959
println(sub)
6060
for kind in ["operations", "generators"]
6161
println(" ", kind)
6262
for num in 1:maxnum
6363
println(" ", num)
6464
gens_str = crawl_subperiodic_xyzt(num, D, P, kind)
65-
filename = (@__DIR__)*"/../data/$kind/subperiodic/$sub/"*string(num)*".csv"
65+
filename = (@__DIR__)*"/../test/data/xyzt-$kind/subperiodic/$sub/"*string(num)*".csv"
6666
open(filename; write=true, create=true, truncate=true) do io
6767
first = true
6868
for str in gens_str
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using Crystalline
2+
using StaticArrays
3+
# --- definitions ---
4+
# to be transferred to Crystalline's definitions
5+
6+
# --- parsing ---
7+
#cd(@__DIR__)
8+
io = open((@__DIR__)*"/../data/operations/msgs/iso-magnetic_table_bns.txt")
9+
10+
# --- read dictionary of operations ---
11+
function read_ops!(io, ops_d, stop_string)
12+
while (str=readline(io); str stop_string)
13+
parts = split(str, isspace; keepempty=false)
14+
code, xyz = parts[1], parts[2]
15+
op = SymOperation(xyz)
16+
ops_d[code] = op
17+
end
18+
return ops_d
19+
end
20+
21+
readuntil(io, "Non-hexagonal groups:"); readline(io)
22+
nonhex_ops_d = Dict{String, SymOperation{3}}()
23+
read_ops!(io, nonhex_ops_d, "Hexagonal groups:")
24+
hex_ops_d = Dict{String, SymOperation{3}}()
25+
read_ops!(io, hex_ops_d, "----------")
26+
27+
# --- read individual groups ---
28+
function parse_opstr(str::AbstractString, ops_d)
29+
str′ = strip(str, ['(', ')','\''])
30+
code, translation_str = split(str′, '|')::Vector{SubString{String}}
31+
translation_parts = split(translation_str, ',')
32+
translation_tup = ntuple(Val(3)) do i
33+
Crystalline.parsefraction(translation_parts[i])
34+
end
35+
translation = SVector{3, Float64}(translation_tup)
36+
op = SymOperation{3}(ops_d[code].rotation, translation)
37+
tr = last(str) == '\''
38+
return MSymOperation(op, tr)
39+
end
40+
41+
function read_group!(io)
42+
# BNS: number & label
43+
readuntil(io, "BNS: ")
44+
num_str = readuntil(io, " ") # numbering in format `sgnum.cnum`
45+
sgnum, cnum = parse.(Int, split(num_str, "."))::Vector{Int}
46+
# `sgnum`: F space-group associated number, `cnum`: crystal-system sequential number
47+
bns_label = replace(readuntil(io, " "), '\''=>'') # BNS label in IUC-style
48+
49+
# OG: number and label
50+
readuntil(io, "OG: ")
51+
N₁N₂N₃_str = readuntil(io, " ") # numbering in format `N₁.N₂.N₃`
52+
N₁, N₂, N₃ = parse.(Int, split(N₁N₂N₃_str, "."))::Vector{Int}
53+
og_label = replace(readuntil(io, '\n'), '\''=>'') # OG label in IUC-style
54+
55+
# operator strings
56+
is_hex = crystalsystem(sgnum) ("hexagonal" , "trigonal")
57+
readuntil(io, "Operators")
58+
c = read(io, Char)
59+
if c == ' '
60+
readuntil(io, "(BNS):")
61+
elseif c ':'
62+
error("unexpected parsing failure")
63+
end
64+
ops_str = readuntil(io, "Wyckoff")
65+
op_strs = split(ops_str, isspace; keepempty=false)
66+
67+
# parse operator strings to operations
68+
g = Vector{MSymOperation{3}}(undef, length(op_strs))
69+
for (i, str) in enumerate(op_strs)
70+
g[i] = parse_opstr(str, is_hex ? hex_ops_d : nonhex_ops_d)
71+
isdone = str[end] == '\n'
72+
isdone && break
73+
end
74+
75+
return MSpaceGroup{3}((sgnum, cnum), g), bns_label, og_label, (N₁, N₂, N₃)
76+
end
77+
msgs = MSpaceGroup{3}[]
78+
MSG_BNS_LABELs_D = Dict{Tuple{Int, Int}, String}()
79+
MSG_OG_LABELs_D = Dict{Tuple{Int, Int, Int}, String}()
80+
MSG_BNS2OG_NUMs_D = Dict{Tuple{Int, Int}, Tuple{Int, Int, Int}}()
81+
for i in 1:1651
82+
msg, bns_label, og_label, (N₁, N₂, N₃) = read_group!(io)
83+
push!(msgs, msg)
84+
MSG_BNS_LABELs_D[msg.num] = bns_label
85+
MSG_OG_LABELs_D[(N₁, N₂, N₃)] = og_label
86+
MSG_BNS2OG_NUMs_D[msg.num] = (N₁, N₂, N₃)
87+
end

data/misc/ISOTROPY/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ISOTROPY ISO-IR dataset
2-
These file `CIR_data.txt` and `PIR_data.txt` are sourced from the
2+
The files `CIR_data.txt` and `PIR_data.txt` are sourced from the
33
[ISOTROPY software's ISO-IR dataset](https://stokes.byu.edu/iso/irtables.php)
44
and contain data needed to generate *space group* irreps.
55
In ISOTROPY, the data files are extracted in Fortran using associated files

0 commit comments

Comments
 (0)