Isosurfaces with space group symmetry

Crystalline.UnityFourierLatticeType
UnityFourierLattice{D} <: AbstractFourierLattice{D}

A general D-dimensional Fourier (plane wave) lattice specified by orbits of reciprocal lattice vectors (orbits) and coefficient interrelations (orbitcoefs)). The norm of all elements in orbitcoefs is unity. orbits (and associated coefficients) are sorted in order of increasing norm (low to high).

source
Crystalline.ModulatedFourierLatticeType
ModulatedFourierLattice{D} <: AbstractFourierLattice{D}

A D-dimensional concrete Fourier (plane wave) lattice, derived from a UnityFourierLattice{D} by scaling and modulating its orbit coefficients by complex numbers; in general, the coefficients do not have unit norm.

source
Crystalline.levelsetlatticeFunction
levelsetlattice(sgnum::Integer, D::Integer=2, idxmax::NTuple=ntuple(i->2,D))
    --> UnityFourierLattice{D}

Compute a "neutral"/uninitialized Fourier lattice basis, a UnityFourierLattice, consistent with the symmetries of the space group sgnum in dimension D. The resulting lattice flat is expanded in a Fourier basis split into symmetry-derived orbits, with intra-orbit coefficients constrained by the symmetries of the space-group. The inter-orbit coefficients are, however, free and unconstrained.

The Fourier resolution along each reciprocal lattice vector is controlled by idxmax: e.g., if D = 2 and idxmax = (2, 3), the resulting Fourier lattice may contain reciprocal lattice vectors (k₁, k₂) with k₁∈[0,±1,±2] and k₂∈[0,±1,±2,±3], referred to a 𝐆-basis.

This "neutral" lattice can, and usually should, be subsequently modulated by modulate (which modulates the inter-orbit coefficients, which may eliminate "synthetic symmetries" that can exist in the "neutral" configuration, due to all inter-orbit coefficients being set to unity).

Examples

Compute a UnityFourierLattice, modulate it with random inter-orbit coefficients via modulate, and finally plot it (via PyPlot.jl):

julia> uflat = levelsetlattice(16, Val(2))
julia> flat  = modulate(uflat)
julia> Rs    = directbasis(16, Val(2)) 
julia> using PyPlot
julia> plot(flat, Rs)
source
Crystalline.modulateFunction
modulate(flat::UnityFourierLattice{D},
modulation::AbstractVector{ComplexF64}=rand(ComplexF64, length(getcoefs(flat))),
expon::Union{Nothing, Real}=nothing, Gs::Union{ReciprocalBasis{D}, Nothing}=nothing)
                        --> ModulatedFourierLattice{D}

Derive a concrete, modulated Fourier lattice from a UnityFourierLattice flat (containing the interrelations between orbit coefficients), by multiplying the "normalized" orbit coefficients by a modulation, a complex modulating vector (in general, should be complex; otherwise restores unintended symmetry to the lattice). Distinct modulation vectors produce distinct realizations of the same lattice described by the original flat. By default, a random complex vector is used.

An exponent expon can be provided, which introduces a penalty term to short- wavelength features (i.e. high-|G| orbits) by dividing the orbit coefficients by |G|^expon; producing a "simpler" and "smoother" lattice boundary when expon > 0 (reverse for expon < 0). This basically amounts to a continuous "simplifying" operation on the lattice (it is not necessarily a smoothing operation; it simply suppresses "high-frequency" components). If expon = nothing, no rescaling is performed. If Gs is provided as nothing, the orbit norm is computed in the reciprocal lattice basis (and, so, may not strictly speaking be a norm if the lattice basis is not cartesian); to account for the basis explicitly, Gs must be provided as a ReciprocalBasis, see also normscale.

source
Bravais.primitivizeMethod
primitivize(flat::AbstractFourierLattice, cntr::Char) --> ::typeof(flat)

Given flat referred to a conventional basis with centering cntr, compute the derived (but physically equivalent) lattice flat′ referred to the associated primitive basis.

Specifically, if flat refers to a direct conventional basis Rs $≡ (\mathbf{a} \mathbf{b} \mathbf{c})$ [with coordinate vectors $\mathbf{r} ≡ (r_1, r_2, r_3)^{\mathrm{T}}$] then flat′ refers to a direct primitive basis Rs′ $≡ (\mathbf{a}' \mathbf{b}' \mathbf{c}') ≡ (\mathbf{a} \mathbf{b} \mathbf{c})\mathbf{P}$ [with coordinate vectors $\mathbf{r}' ≡ (r_1', r_2', r_3')^{\mathrm{T}} = \mathbf{P}^{-1}\mathbf{r}$], where $\mathbf{P}$ denotes the basis-change matrix obtained from primitivebasismatrix(...).

To compute the associated primitive basis vectors, see primitivize(::DirectBasis, ::Char) [specifically, Rs′ = primitivize(Rs, cntr)].

Examples

A centered ('c') lattice from plane group 5 in 2D, plotted in its conventional and primitive basis (requires using PyPlot):

julia> sgnum = 5; D = 2; cntr = centering(sgnum, D)  # 'c' (body-centered)

julia> Rs   = directbasis(sgnum, Val(D))     # conventional basis (rectangular)
julia> flat = levelsetlattice(sgnum, Val(D)) # Fourier lattice in basis of Rs
julia> flat = modulate(flat)                 # modulate the lattice coefficients
julia> plot(flat, Rs)

julia> Rs′   = primitivize(Rs, cntr)    # primitive basis (oblique)
julia> flat′ = primitivize(flat, cntr)  # Fourier lattice in basis of Rs′

julia> using PyPlot
julia> plot(flat′, Rs′)
source
Bravais.conventionalizeMethod
conventionalize(flat::AbstractFourierLattice, cntr::Char) --> ::typeof(flat′)

Given flat referred to a primitive basis with centering cntr, compute the derived (but physically equivalent) lattice flat′ referred to the associated conventional basis.

See also the complementary method primitivize(::AbstractFourierLattice, ::Char) for additional details.

source
Crystalline.AbstractFourierLatticeMethod
(flat::AbstractFourierLattice)(xyz) --> Float64
(flat::AbstractFourierLattice)(xyzs...) --> Float64

Evaluate an AbstractFourierLattice at the point xyz and return its real part, i.e.

\[ \mathop{\mathrm{Re}}\sum_i c_i \exp(2\pi i\mathbf{G}_i\cdot\mathbf{r})\]

with $\mathrm{G}_i$ denoting reciprocal lattice vectors in the allowed orbits of flat, with $c_i$ denoting the associated coefficients (and $\mathbf{r} \equiv$ xyz).

xyz may be any iterable object with dimension matching flat consisting of real numbers (e.g., a Tuple, Vector, or SVector). Alternatively, the coordinates can be supplied individually (i.e., as flat(x, y, z)).

source