Skip to content

Commit

Permalink
Refactor reshape_supercell_aux
Browse files Browse the repository at this point in the history
  • Loading branch information
kbarros committed Jul 15, 2024
1 parent 81e2656 commit 41a6096
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
18 changes: 7 additions & 11 deletions src/Reshaping.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ function reshape_supercell(sys::System{N}, shape) where N
@assert prim_shape′ prim_shape

# Unit cell for new system, in units of original unit cell.
enlarged_latsize = NTuple{3, Int}(gcd.(eachcol(prim_shape′)))
reduced_shape = Mat3(shape * diagm(collect(inv.(enlarged_latsize))))
new_latsize = NTuple{3, Int}(gcd.(eachcol(prim_shape′)))
new_shape = Mat3(shape * diagm(collect(inv.(new_latsize))))
new_cryst = reshape_crystal(orig_crystal(sys), new_shape)

return reshape_supercell_aux(sys, enlarged_latsize, reduced_shape)
return reshape_supercell_aux(sys, new_cryst, new_latsize)
end


Expand Down Expand Up @@ -59,12 +60,9 @@ function transfer_interactions!(sys::System{N}, src::System{N}) where N
end


function reshape_supercell_aux(sys::System{N}, new_latsize::NTuple{3, Int}, new_cell_shape::Mat3) where N
# Reshape the crystal
new_cryst = reshape_crystal(orig_crystal(sys), new_cell_shape)
new_na = natoms(new_cryst)

function reshape_supercell_aux(sys::System{N}, new_cryst::Crystal, new_latsize::NTuple{3, Int}) where N
# Allocate data for new system, but with an empty list of interactions
new_na = natoms(new_cryst)
new_Ns = zeros(Int, new_latsize..., new_na)
new_κs = zeros(Float64, new_latsize..., new_na)
new_gs = zeros(Mat3, new_latsize..., new_na)
Expand Down Expand Up @@ -143,7 +141,5 @@ See also [`reshape_supercell`](@ref).
"""
function repeat_periodically(sys::System{N}, counts::NTuple{3,Int}) where N
all(>=(1), counts) || error("Require at least one count in each direction.")

# Scale each column by `counts` and reshape
return reshape_supercell_aux(sys, counts .* sys.latsize, cell_shape(sys))
return reshape_supercell_aux(sys, sys.crystal, counts .* sys.latsize)
end
22 changes: 18 additions & 4 deletions src/SpinWaveTheory/SpinWaveTheory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,24 @@ struct SpinWaveTheory
end

function SpinWaveTheory(sys::System{N}; energy_ϵ::Float64=1e-8, observables=nothing, correlations=nothing, apply_g=true) where N
# Reshape into single unit cell. A clone will always be performed, even if
# no reshaping happens.
cellsize_mag = cell_shape(sys) * diagm(Vec3(sys.latsize))
sys = reshape_supercell_aux(sys, (1,1,1), cellsize_mag)
# Create single chemical cell that matches the full system size.
new_shape = cell_shape(sys) * diagm(Vec3(sys.latsize))
new_cryst = reshape_crystal(orig_crystal(sys), new_shape)

# Sort crystal positions so that their order matches sites in sys. Quadratic
# scaling in system size.
global_positions = global_position.(Ref(sys), vec(eachsite(sys)))
p = map(new_cryst.positions) do r
pos = new_cryst.latvecs * r
findfirst(global_positions) do refpos
isapprox(pos, refpos, atol=new_cryst.symprec)
end
end
@assert allunique(p)
permute_sites!(new_cryst, p)

# Create a new system with latsize (1,1,1). A clone happens in all cases.
sys = reshape_supercell_aux(sys, new_cryst, (1,1,1))

# Rotate local operators to quantization axis
if sys.mode == :SUN
Expand Down
20 changes: 15 additions & 5 deletions src/Symmetry/Crystal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,19 @@ function spacegroup_name(hall_number::Int)
end


# Sort the sites according to class and fractional coordinates.
# Crystal is immutable in its public API. Therefore, this is an internal
# function should not overload Base.permute!
function permute_sites!(cryst::Crystal, p)
cryst.positions .= cryst.positions[p]
cryst.classes .= cryst.classes[p]
cryst.types .= cryst.types[p]
if !isnothing(cryst.sitesyms)
cryst.sitesyms .= cryst.sitesyms[p]
end
end

# Sort the sites according to class and fractional coordinates. This is an
# internal function.
function sort_sites!(cryst::Crystal)
function less_than(i, j)
ci = cryst.classes[i]
Expand All @@ -171,10 +183,8 @@ function sort_sites!(cryst::Crystal)
error("""Detected two very close atoms ($str1 and $str2).
If positions inferred from spacegroup, try increasing `symprec` parameter to `Crystal`.""")
end
perm = sort(eachindex(cryst.positions), lt=less_than)
cryst.positions .= cryst.positions[perm]
cryst.classes .= cryst.classes[perm]
cryst.types .= cryst.types[perm]
p = sort(eachindex(cryst.positions), lt=less_than)
permute_sites!(cryst, p)
end


Expand Down

0 comments on commit 41a6096

Please sign in to comment.