Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JuliaFormatter exploration #200

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
style = "blue"
import_to_using = false
whitespace_ops_in_indices = false
normalize_line_endings = "unix"
# align_assignment = true
# align_struct_field = true
align_conditional = true
align_pair_arrow = true
align_matrix = true
ignore = ["docs"]
48 changes: 48 additions & 0 deletions .github/workflows/FormatCheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: format-check

on:
push:
branches:
- 'main'
- 'release-'
tags: '*'
pull_request:

concurrency:
# Skip intermediate builds: always, but for the main branch and tags.
# Cancel intermediate builds: always, but for the main branch and tags.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.refs != 'refs/tags/*'}}

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia-version }}

- uses: actions/checkout@v4
- name: Install JuliaFormatter and format
# This will use the latest version by default but you can set the version like so:
#
# julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter", version="0.13.0"))'
run: |
julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))'
julia -e 'using JuliaFormatter; format(".", verbose=true)'
- name: Format check
run: |
julia -e '
out = Cmd(`git diff`) |> read |> String
if out == ""
exit(0)
else
@error "Some files have not been formatted !!!"
write(stdout, out)
exit(1)
end'
134 changes: 91 additions & 43 deletions examples/01_LSWT_SU3_FeI2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ a = b = 4.05012 # Lattice constants for triangular lattice
c = 6.75214 # Spacing in the z-direction

latvecs = lattice_vectors(a, b, c, 90, 90, 120) # A 3x3 matrix of lattice vectors that
## define the conventional unit cell
positions = [[0, 0, 0], [1/3, 2/3, 1/4], [2/3, 1/3, 3/4]] # Positions of atoms in fractions
## of lattice vectors
## define the conventional unit cell
positions = [[0, 0, 0], [1 / 3, 2 / 3, 1 / 4], [2 / 3, 1 / 3, 3 / 4]] # Positions of atoms in fractions
## of lattice vectors
types = ["Fe", "I", "I"]
FeI2 = Crystal(latvecs, positions; types)

Expand Down Expand Up @@ -107,7 +107,7 @@ print_symmetry_table(cryst, 8.0)
# In constructing a spin [`System`](@ref), we must provide several additional
# details about the spins.

sys = System(cryst, (4, 4, 4), [SpinInfo(1, S=1, g=2)], :SUN, seed=2)
sys = System(cryst, (4, 4, 4), [SpinInfo(1; S=1, g=2)], :SUN; seed=2)

# This system includes $4×4×4$ unit cells, i.e. 64 Fe atoms, each with spin $S=1$
# and a $g$-factor of 2. Quantum mechanically, spin $S=1$ involves a
Expand All @@ -121,52 +121,88 @@ sys = System(cryst, (4, 4, 4), [SpinInfo(1, S=1, g=2)], :SUN, seed=2)
# in the unit cell. The FeI₂ interactions below follow [Bai et
# al](https://doi.org/10.1038/s41567-020-01110-1).

J1pm = -0.236
J1pm = -0.236
J1pmpm = -0.161
J1zpm = -0.261
J2pm = 0.026
J3pm = 0.166
J′0pm = 0.037
J′1pm = 0.013
J1zpm = -0.261
J2pm = 0.026
J3pm = 0.166
J′0pm = 0.037
J′1pm = 0.013
J′2apm = 0.068

J1zz = -0.236
J2zz = 0.113
J3zz = 0.211
J′0zz = -0.036
J′1zz = 0.051
J1zz = -0.236
J2zz = 0.113
J3zz = 0.211
J′0zz = -0.036
J′1zz = 0.051
J′2azz = 0.073

J1xx = J1pm + J1pmpm
J1xx = J1pm + J1pmpm
J1yy = J1pm - J1pmpm
J1yz = J1zpm

set_exchange!(sys, [J1xx 0.0 0.0;
0.0 J1yy J1yz;
0.0 J1yz J1zz], Bond(1,1,[1,0,0]))
set_exchange!(sys, [J2pm 0.0 0.0;
0.0 J2pm 0.0;
0.0 0.0 J2zz], Bond(1,1,[1,2,0]))
set_exchange!(sys, [J3pm 0.0 0.0;
0.0 J3pm 0.0;
0.0 0.0 J3zz], Bond(1,1,[2,0,0]))
set_exchange!(sys, [J′0pm 0.0 0.0;
0.0 J′0pm 0.0;
0.0 0.0 J′0zz], Bond(1,1,[0,0,1]))
set_exchange!(sys, [J′1pm 0.0 0.0;
0.0 J′1pm 0.0;
0.0 0.0 J′1zz], Bond(1,1,[1,0,1]))
set_exchange!(sys, [J′2apm 0.0 0.0;
0.0 J′2apm 0.0;
0.0 0.0 J′2azz], Bond(1,1,[1,2,1]))
set_exchange!(
sys,
[
J1xx 0.0 0.0
0.0 J1yy J1yz
0.0 J1yz J1zz
],
Bond(1, 1, [1, 0, 0]),
)
set_exchange!(
sys,
[
J2pm 0.0 0.0
0.0 J2pm 0.0
0.0 0.0 J2zz
],
Bond(1, 1, [1, 2, 0]),
)
set_exchange!(
sys,
[
J3pm 0.0 0.0
0.0 J3pm 0.0
0.0 0.0 J3zz
],
Bond(1, 1, [2, 0, 0]),
)
set_exchange!(
sys,
[
J′0pm 0.0 0.0
0.0 J′0pm 0.0
0.0 0.0 J′0zz
],
Bond(1, 1, [0, 0, 1]),
)
set_exchange!(
sys,
[
J′1pm 0.0 0.0
0.0 J′1pm 0.0
0.0 0.0 J′1zz
],
Bond(1, 1, [1, 0, 1]),
)
set_exchange!(
sys,
[
J′2apm 0.0 0.0
0.0 J′2apm 0.0
0.0 0.0 J′2azz
],
Bond(1, 1, [1, 2, 1]),
)

# The function [`set_onsite_coupling!`](@ref) assigns a single-ion anisotropy.
# The argument can be constructed using [`spin_matrices`](@ref) or
# [`stevens_matrices`](@ref). Here we use Julia's anonymous function syntax to
# assign an easy-axis anisotropy along the direction $\hat{z}$.

D = 2.165
set_onsite_coupling!(sys, S -> -D*S[3]^2, 1)
set_onsite_coupling!(sys, S -> -D * S[3]^2, 1)

# # Calculating structure factor intensities

Expand Down Expand Up @@ -226,7 +262,7 @@ print_wrapped_intensities(sys)
# wavevectors, $Q = [0, -1/4, 1/4]$. Sunny suggests a corresponding magnetic
# supercell in units of the crystal lattice vectors.

suggest_magnetic_supercell([[0, -1/4, 1/4]])
suggest_magnetic_supercell([[0, -1 / 4, 1 / 4]])

# The system returned by [`reshape_supercell`](@ref) is smaller, and is sheared
# relative to the original system. This makes it much easier to find the global
Expand All @@ -252,7 +288,7 @@ swt = SpinWaveTheory(sys_min)
# Select a sequence of wavevectors that will define a piecewise linear
# interpolation in reciprocal lattice units (RLU).

q_points = [[0,0,0], [1,0,0], [0,1,0], [1/2,0,0], [0,1,0], [0,0,0]];
q_points = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1 / 2, 0, 0], [0, 1, 0], [0, 0, 0]];

# The function [`reciprocal_space_path`](@ref) will linearly sample a `path`
# between the provided $q$-points with a given `density`. The `xticks` return
Expand Down Expand Up @@ -283,12 +319,18 @@ disp, intensity = intensities_bands(swt, path, formula);
# These can be plotted in GLMakie.

fig = Figure()
ax = Axis(fig[1,1]; xlabel="Momentum (r.l.u.)", ylabel="Energy (meV)", xticks, xticklabelrotation=π/6)
ax = Axis(
fig[1, 1];
xlabel="Momentum (r.l.u.)",
ylabel="Energy (meV)",
xticks,
xticklabelrotation=π / 6,
)
ylims!(ax, 0.0, 7.5)
xlims!(ax, 1, size(disp, 1))
colorrange = extrema(intensity)
for i in axes(disp, 2)
lines!(ax, 1:length(disp[:,i]), disp[:,i]; color=intensity[:,i], colorrange)
lines!(ax, 1:length(disp[:, i]), disp[:, i]; color=intensity[:, i], colorrange)
end
fig

Expand All @@ -314,13 +356,19 @@ is1 = intensities_broadened(swt, path, energies, broadened_formula);
# [`rotation_in_rlu`](@ref) to average the intensities over all three possible
# orientations.

R = rotation_in_rlu(cryst, [0, 0, 1], 2π/3)
is2 = intensities_broadened(swt, [R*q for q in path], energies, broadened_formula)
is3 = intensities_broadened(swt, [R*R*q for q in path], energies, broadened_formula)
R = rotation_in_rlu(cryst, [0, 0, 1], 2π / 3)
is2 = intensities_broadened(swt, [R * q for q in path], energies, broadened_formula)
is3 = intensities_broadened(swt, [R * R * q for q in path], energies, broadened_formula)
is_averaged = (is1 + is2 + is3) / 3

fig = Figure()
ax = Axis(fig[1,1]; xlabel="Momentum (r.l.u.)", ylabel="Energy (meV)", xticks, xticklabelrotation=π/6)
ax = Axis(
fig[1, 1];
xlabel="Momentum (r.l.u.)",
ylabel="Energy (meV)",
xticks,
xticklabelrotation=π / 6,
)
heatmap!(ax, 1:size(is_averaged, 1), energies, is_averaged)
fig

Expand Down
46 changes: 27 additions & 19 deletions examples/02_LSWT_CoRh2O4.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ using Sunny, GLMakie

a = 8.5031 # (Å)
latvecs = lattice_vectors(a, a, a, 90, 90, 90)
cryst = Crystal(latvecs, [[0,0,0]], 227, setting="1")
cryst = Crystal(latvecs, [[0, 0, 0]], 227; setting="1")

# In a running Julia environment, the crystal can be viewed interactively using
# [`view_crystal`](@ref).
Expand All @@ -31,10 +31,10 @@ view_crystal(cryst, 8.0)
# repeatable results.

latsize = (1, 1, 1)
S = 3/2
J = 7.5413*meV_per_K # (~ 0.65 meV)
S = 3 / 2
J = 7.5413 * meV_per_K # (~ 0.65 meV)
sys = System(cryst, latsize, [SpinInfo(1; S, g=2)], :dipole; seed=0)
set_exchange!(sys, J, Bond(1, 3, [0,0,0]))
set_exchange!(sys, J, Bond(1, 3, [0, 0, 0]))

# In the ground state, each spin is exactly anti-aligned with its 4
# nearest-neighbors. Because every bond contributes an energy of $-JS^2$, the
Expand All @@ -45,25 +45,27 @@ set_exchange!(sys, J, Bond(1, 3, [0,0,0]))
randomize_spins!(sys)
minimize_energy!(sys)

@assert energy_per_site(sys) ≈ -2J*S^2
@assert energy_per_site(sys) ≈ -2J * S^2

# Plotting the spins confirms the expected Néel order. Note that the overall,
# global rotation of dipoles is arbitrary.

s0 = sys.dipoles[1,1,1,1]
plot_spins(sys; color=[s'*s0 for s in sys.dipoles])
s0 = sys.dipoles[1, 1, 1, 1]
plot_spins(sys; color=[s' * s0 for s in sys.dipoles])

# For numerical efficiency, it is helpful to work with the smallest possible
# magnetic supercell; in this case, it is the primitive cell. The columns of the
# 3×3 `shape` matrix define the lattice vectors of the primitive cell as
# multiples of the conventional, cubic lattice vectors. After transforming the
# system with [`reshape_supercell`](@ref), the energy per site remains the same.
shape = [0 1 1;
1 0 1;
1 1 0] / 2
shape = [
0 1 1
1 0 1
1 1 0
] / 2
sys_prim = reshape_supercell(sys, shape)
@assert energy_per_site(sys_prim) ≈ -2J*S^2
plot_spins(sys_prim; color=[s'*s0 for s in sys_prim.dipoles])
@assert energy_per_site(sys_prim) ≈ -2J * S^2
plot_spins(sys_prim; color=[s' * s0 for s in sys_prim.dipoles])

# Now estimate ``𝒮(𝐪,ω)`` with [`SpinWaveTheory`](@ref) and an
# [`intensity_formula`](@ref). The mode `:perp` contracts with a dipole factor
Expand All @@ -82,15 +84,21 @@ formula = intensity_formula(swt, :perp; kernel, formfactors)
# [`intensities_broadened`](@ref) function collects intensities along this path
# for the given set of energy values.

qpoints = [[0, 0, 0], [1/2, 0, 0], [1/2, 1/2, 0], [0, 0, 0]]
qpoints = [[0, 0, 0], [1 / 2, 0, 0], [1 / 2, 1 / 2, 0], [0, 0, 0]]
path, xticks = reciprocal_space_path(cryst, qpoints, 50)
energies = collect(0:0.01:6)
is = intensities_broadened(swt, path, energies, formula)

fig = Figure()
ax = Axis(fig[1,1]; aspect=1.4, ylabel="ω (meV)", xlabel="𝐪 (r.l.u.)",
xticks, xticklabelrotation=π/10)
heatmap!(ax, 1:size(is, 1), energies, is, colormap=:gnuplot2)
ax = Axis(
fig[1, 1];
aspect=1.4,
ylabel="ω (meV)",
xlabel="𝐪 (r.l.u.)",
xticks,
xticklabelrotation=π / 10,
)
heatmap!(ax, 1:size(is, 1), energies, is; colormap=:gnuplot2)
fig

# A powder measurement effectively involves an average over all possible crystal
Expand All @@ -104,12 +112,12 @@ for (i, radius) in enumerate(radii)
n = 300
qs = reciprocal_space_shell(cryst, radius, n)
is = intensities_broadened(swt, qs, energies, formula)
output[i, :] = sum(is, dims=1) / size(is, 1)
output[i, :] = sum(is; dims=1) / size(is, 1)
end

fig = Figure()
ax = Axis(fig[1,1]; xlabel="Q (Å⁻¹)", ylabel="ω (meV)")
heatmap!(ax, radii, energies, output, colormap=:gnuplot2)
ax = Axis(fig[1, 1]; xlabel="Q (Å⁻¹)", ylabel="ω (meV)")
heatmap!(ax, radii, energies, output; colormap=:gnuplot2)
fig

# This result can be compared to experimental neutron scattering data
Expand Down
Loading
Loading