diff --git a/docs/src/versions.md b/docs/src/versions.md index 5f6dd87ac..e37d27f76 100644 --- a/docs/src/versions.md +++ b/docs/src/versions.md @@ -6,7 +6,9 @@ * [`view_crystal`](@ref) called on a [`System`](@ref) now optionally shows spin or magnetic dipoles. * Interactions for [`enable_dipole_dipole!`](@ref) are now supported in linear - spin wave theory, with proper Ewald summation. + spin wave theory, with proper Ewald summation. For a faster alternative, the + experimental function [`modify_exchange_with_truncated_dipole_dipole!`](@ref) + will accept a real-space cutoff. ## v0.5.9 diff --git a/examples/07_Dipole_Dipole.jl b/examples/07_Dipole_Dipole.jl index a7b8f2ce6..28fc6fda8 100644 --- a/examples/07_Dipole_Dipole.jl +++ b/examples/07_Dipole_Dipole.jl @@ -45,13 +45,13 @@ xticks = (xticks[1], q_labels) swt = SpinWaveTheory(sys_prim) disp1 = dispersion(swt, path) -sys_prim′ = Sunny.clone_system(sys_prim) +sys_prim′ = clone_system(sys_prim) enable_dipole_dipole!(sys_prim′) swt = SpinWaveTheory(sys_prim′) disp2 = dispersion(swt, path); -sys_prim′ = Sunny.clone_system(sys_prim) -Sunny.accum_dipole_dipole_locally!(sys_prim′, 5.0) # Experimental function +sys_prim′ = clone_system(sys_prim) +modify_exchange_with_truncated_dipole_dipole!(sys_prim′, 5.0) swt = SpinWaveTheory(sys_prim′) disp3 = dispersion(swt, path); diff --git a/src/Sunny.jl b/src/Sunny.jl index b6c5ef402..f325ca738 100644 --- a/src/Sunny.jl +++ b/src/Sunny.jl @@ -56,7 +56,8 @@ export SpinInfo, System, Site, clone_system, eachsite, position_to_site, global_ set_coherent!, set_dipole!, polarize_spins!, randomize_spins!, set_spin_rescaling!, energy, energy_per_site, spin_label, set_onsite_coupling!, set_pair_coupling!, set_exchange!, dmvec, enable_dipole_dipole!, set_external_field!, to_inhomogeneous, set_external_field_at!, set_vacancy_at!, set_onsite_coupling_at!, - set_exchange_at!, set_pair_coupling_at!, symmetry_equivalent_bonds, remove_periodicity! + set_exchange_at!, set_pair_coupling_at!, symmetry_equivalent_bonds, remove_periodicity!, + modify_exchange_with_truncated_dipole_dipole! include("MagneticOrdering.jl") export print_wrapped_intensities, suggest_magnetic_supercell, set_spiral_order!, set_spiral_order_on_sublattice! diff --git a/src/System/Ewald.jl b/src/System/Ewald.jl index aef527f01..aff6a35b8 100644 --- a/src/System/Ewald.jl +++ b/src/System/Ewald.jl @@ -237,14 +237,31 @@ function ewald_energy_delta(sys::System{N}, site, s::Vec3) where N return Δs⋅∇E + dot(Δμ, ewald.A[1, 1, 1, i, i], Δμ) / 2 end - -# Adds dipole-dipole interactions on top of existing exchange interactions. -function accum_dipole_dipole_locally!(sys::System{N}, cutoff) where N +""" + modify_exchange_with_truncated_dipole_dipole!(sys::System, cutoff) + +This *experimental* function is subject to change. + +Like [`enable_dipole_dipole!`](@ref), the purpose of this function is to +introduce long-range dipole-dipole interactions between magnetic moments. +Whereas `enable_dipole_dipole!` employs Ewald summation, this function instead +employs real-space pair couplings, with truncation at some user-specified +`cutoff` distance. If the cutoff is relatively small, then this function can be +faster than `enable_dipole_dipole!`, especially for spin wave theory +calculations. + +**Caution**. This function will modify existing bilinear couplings between spins +by adding dipole-dipole interactions. It must therefore be called _after_ all +other pair couplings have been specified. Conversely, any calls to +`set_exchange!`, `set_pair_coupling!`, etc. will irreversibly delete the +dipole-dipole interactions that have been introduced by this function. +""" +function modify_exchange_with_truncated_dipole_dipole!(sys::System{N}, cutoff) where N (; gs) = sys (; μB, μ0) = sys.units if !isnothing(sys.origin) - accum_dipole_dipole_locally!(sys.origin, cutoff) + modify_exchange_with_truncated_dipole_dipole!(sys.origin, cutoff) transfer_interactions!(sys, sys.origin) return end