Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
kbarros committed Jun 18, 2024
1 parent 6215ae6 commit 280f614
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 36 deletions.
4 changes: 4 additions & 0 deletions docs/src/versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
independent of the calculator ([Issue
264](https://github.com/SunnySuite/Sunny.jl/issues/264)). Consequently, color
ranges in plots may need to be rescaled.
* [`Crystal`](@ref) can now infer a chemical unit cell from an mcif file.
`System` now supports [`set_dipoles_from_mcif!`](@ref). Through spglib, one
can now [`standardize`](@ref) any `Crystal`, with an option to idealize site
positions.

## v0.5.11
(June 2, 2024)
Expand Down
63 changes: 27 additions & 36 deletions src/Symmetry/Crystal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,22 +178,21 @@ function sort_sites!(cryst::Crystal)
end

"""
standardize(cryst::Crystal)
standardize(cryst::Crystal; idealize=false)
Return the standardized crystal unit cell, with idealization of the lattice
vectors and site positions. See "definitions and conventions" of the [spglib
Return the symmetry-inferred standardized crystal unit cell. If `idealize=true`,
then the lattice vectors and site positions will be adapted. See "definitions
and conventions" of the [spglib
documentation](https://spglib.readthedocs.io/en/stable/) for more information.
"""
function standardize(cryst::Crystal)
(; latvecs, positions, types, symprec) = cryst
cell = Spglib.Cell(latvecs, positions, types)
d = Spglib.get_dataset(cell, symprec)
(; std_lattice, std_positions, std_types) = d
# Sort atoms to make types contiguous
P = sortperm(std_types)
new_positions = std_positions[P]
new_types = unique(types)[std_types[P]]
return crystal_from_inferred_symmetry(Mat3(std_lattice), new_positions, new_types; symprec)
function standardize(cryst::Crystal; idealize=false)
# Infer standardized cell
(; symprec) = cryst
cell = Spglib.Cell(cryst.latvecs, cryst.positions, cryst.types)
std_cell = Spglib.standardize_cell(cell, symprec; no_idealize=!idealize)
ret = crystal_from_inferred_symmetry(Mat3(std_cell.lattice), Vec3.(std_cell.positions), std_cell.atoms; symprec)
sort_sites!(ret)
return ret
end

function crystal_from_inferred_symmetry(latvecs::Mat3, positions::Vector{Vec3}, types::Vector{String}; symprec=1e-5, check_cell=true)
Expand All @@ -220,21 +219,13 @@ function crystal_from_inferred_symmetry(latvecs::Mat3, positions::Vector{Vec3},
ratio = length(positions) / d.n_std_atoms
if ratio > 1
ratio_str = number_to_simple_string(ratio; digits=4)
(a, b, c, α, β, γ) = number_to_math_string.(lattice_params(d.std_lattice); digits=8)
latstr = "lattice_vectors($a, $b, $c, , , )"
position_str = "["*join(fractional_vec3_to_string.(d.std_positions), ", ")*"]"
crystal_build_str = if allequal(d.std_types)
"Crystal(latvecs, positions)"
types_str = if !allunique(types)
"\nAlternatively, use `types` argument to break site symmetry."
else
types_str = "["*join(repr.(string.(d.std_types)), ", ")*"]"
"types = $types_str\n Crystal(latvecs, positions; types)"
""
end
@warn """There exists another unit cell that is $ratio_str times smaller. Symmetry
information may be incomplete. Consider using the smaller unit cell:
latvecs = $latstr
positions = $position_str
$crystal_build_str
Alternatively, site symmetry can be broken with a `types` argument."""
@warn """The symmetry-inferred, standardized unit cell is $ratio_str times smaller
than this crystal. Use `standardize` to see the conventional chemical cell.$types_str"""
end
end

Expand Down Expand Up @@ -370,6 +361,14 @@ function crystal_from_symbol(latvecs::Mat3, positions::Vector{Vec3}, types::Vect
end
end

function symops_subset(symops1, symops2; symprec)
return all(symops1) do s
any(symops2) do s′
isapprox(s, s′; atol=symprec)
end
end
end

# Builds a crystal from an explicit set of symmetry operations and a minimal set of positions
function crystal_from_symops(latvecs::Mat3, positions::Vector{Vec3}, types::Vector{String}, symops::Vector{SymOp}, spacegroup::String; symprec=1e-5)
all_positions = Vec3[]
Expand Down Expand Up @@ -406,16 +405,8 @@ function crystal_from_symops(latvecs::Mat3, positions::Vector{Vec3}, types::Vect
inferred = crystal_from_inferred_symmetry(latvecs, all_positions, all_types; symprec, check_cell=false)

# Compare the inferred symops to the provided ones
is_subgroup = all(symops) do s
any(inferred.symops) do s′
isapprox(s, s′; atol=symprec)
end
end
is_supergroup = all(inferred.symops) do s
any(symops) do s′
isapprox(s, s′; atol=symprec)
end
end
is_subgroup = symops_subset(symops, inferred.symops; symprec)
is_supergroup = symops_subset(inferred.symops, symops; symprec)

if !is_subgroup
@warn """User provided symmetry operation could not be inferred by Spglib,
Expand Down

0 comments on commit 280f614

Please sign in to comment.