# Internals

Note

The functions, methods and types documented here are not part of the public API.

AtomicLevels.MQType
const MQ = Union{Int,Symbol}

Defines the possible types that may represent the main quantum number. It can either be an non-negative integer or a Symbol value (generally used to label continuum electrons).

source
AtomicLevels.final_termsMethod
final_terms(ts::Vector{<:Vector{<:Union{Term,Real}}})

Generate all possible final terms from the vector of vectors of individual subshell terms by coupling from left to right.

Examples

julia> ts = [[T"1S", T"3S"], [T"2P", T"2D"]]
2-element Vector{Vector{Term}}:
[¹S, ³S]
[²P, ²D]

julia> AtomicLevels.final_terms(ts)
4-element Vector{Term}:
²P
²D
⁴P
⁴D
source
AtomicLevels.get_noble_core_nameMethod
get_noble_core_name(config::Configuration)

Returns the name of the noble gas with the most electrons whose configuration still forms the first part of the closed part of config, or nothing if no such element is found.

julia> AtomicLevels.get_noble_core_name(c"[He] 2s2")
"He"

julia> AtomicLevels.get_noble_core_name(c"1s2c 2s2c 2p6c 3s2c")
"Ne"

julia> AtomicLevels.get_noble_core_name(c"1s2") === nothing
true
source
AtomicLevels.orbital_priorityMethod
orbital_priority(fun, orig_cfg, orbitals)

Generate priorities for the substitution orbitals, i.e. the preferred ordering of the orbitals in configurations excited from orig_cfg. fun can optionally transform the labels of substitution orbitals, in which case they will be ordered just after their parent orbital in the source configuration; otherwise they will be appended to the priority list.

source
AtomicLevels.rconfigurations_from_orbitalMethod
rconfigurations_from_orbital(orbital::Orbital, occupancy)

Generate all Configurations with relativistic orbitals corresponding to the non-relativistic version of the orbital with a given occupancy.

Examples

julia> AtomicLevels.rconfigurations_from_orbital(o"3p", 2)
3-element Vector{Configuration{var"#s00"} where var"#s00"<:RelativisticOrbital}:
3p-²
3p- 3p
3p²
source
AtomicLevels.rconfigurations_from_orbitalMethod
rconfigurations_from_orbital(n, ℓ, occupancy)

Generate all Configurations with relativistic orbitals corresponding to the non-relativistic orbital with n and ℓ quantum numbers, with given occupancy.

Examples

julia> AtomicLevels.rconfigurations_from_orbital(3, 1, 2)
3-element Vector{Configuration{var"#s00"} where var"#s00"<:RelativisticOrbital}:
3p-²
3p- 3p
3p²
source
Base.:+Method
+(::Configuration, ::Configuration)

Add two configurations together. If both configuration have an orbital, the number of electrons gets added together, but in this case the status of the orbitals must match.

julia> c"1s" + c"2s"
1s 2s

julia> c"1s" + c"1s"
1s²
source
Base.:-Method
-(configuration::Configuration, orbital::AbstractOrbital[, n=1])

Remove n electrons in the orbital orbital from the configuration configuration. If the orbital had previously been :closed or :inactive, it will now be :open.

source
Base.:==Method
==(a::Configuration, b::Configuration)

Tests if configurations a and b are the same, considering orbital occupancy, ordering, and states.

Examples

julia> c"1s 2s" == c"1s 2s"
true

julia> c"1s 2s" == c"1s 2si"
false

julia> c"1s 2s" == c"2s 1s"
false
source
Base.delete!Method
delete!(c::Configuration, o::AbstractOrbital)

Remove the entire subshell corresponding to orbital o from configuration c.

julia> delete!(c"[Ar] 4s2 3d10 4p2", o"4s")
[Ar]ᶜ 3d¹⁰ 4p²
source
Base.filterMethod
filter(f, c::Configuration) -> Configuration

Filter out the orbitals from configuration c for which the predicate f returns false. The predicate f needs to take three arguments: orbital, occupancy and state.

julia> filter((o,occ,s) -> o.ℓ == 1, c"[Kr]")
2p⁶ᶜ 3p⁶ᶜ 4p⁶ᶜ
source
Base.inMethod
in(o::AbstractOrbital, c::Configuration) -> Bool

Checks if orbital o is part of configuration c.

julia> in(o"2s", c"1s2 2s2")
true

julia> o"2p" ∈ c"1s2 2s2"
false
source
Base.islessMethod
isless(a::Orbital, b::Orbital)

Compares the orbitals a and b to decide which one comes before the other in a configuration.

Examples

julia> o"1s" < o"2s"
true

julia> o"1s" < o"2p"
true

julia> o"ks" < o"2p"
false
source
Base.replaceMethod
replace(conf, a => b[; append=false])

Substitute one electron in orbital a of conf by one electron in orbital b. If conf is unsorted the substitution is performed in-place, unless append, in which case the new orbital is appended instead.

Examples

julia> replace(c"1s2 2s", o"1s" => o"2p")
1s 2p 2s

julia> replace(c"1s2 2s", o"1s" => o"2p", append=true)
1s 2s 2p

julia> replace(c"1s2 2s"s, o"1s" => o"2p")
1s 2s 2p
source

## Internal implementation of term multiplicity calculation

AtomicLevels.jl uses the algorithm presented in

to compute the multiplicity of individual subshells in $LS$-coupling, beyond the trivial cases of a single electron or a filled subshell. These routines need not be used directly, instead use terms and count_terms.

In the following, $S'=2S\in\mathbb{Z}$ and $M_S'=2M_S\in\mathbb{Z}$, as in the original article.

AtomicLevels.Xu.XFunction
X(N, ℓ, S′, L)

Calculate the multiplicity of the term $^{2S+1}L$ ($S'=2S$) for the orbital ℓ with occupancy N, according to the formula:

\begin{aligned} X(N, \ell, S', L) =&+ A(N, \ell,\ell,S',L)\\ &- A(N, \ell,\ell,S',L+1)\\ &+A(N, \ell,\ell,S'+2,L+1)\\ &- A(N, \ell,\ell,S'+2,L) \end{aligned}

Note that this is not correct for filled (empty) shells, for which the only possible term trivially is ¹S.

Examples

julia> AtomicLevels.Xu.X(1, 0, 1, 0) # Multiplicity of ²S term for s¹
1

julia> AtomicLevels.Xu.X(3, 3, 1, 3) # Multiplicity of ²D term for d³
2
source
AtomicLevels.Xu.AFunction

$A(N,\ell,\ell_b,M_S',M_L)$ obeys four different cases:

Case 1

$M_S'=1$, $|M_L|\leq\ell$, and $N=1$:

$$$A(1,\ell,\ell_b,1,M_L) = 1$$$

Case 2

$\{M_S'\}={2-N,4-N,...,N-2}$, $|M_L| \leq f\left(\frac{N-M_S'}{2}-1\right)+f\left(\frac{N+M_S'}{2}-1\right)$, and $1<N\leq 2\ell+1$:

\begin{aligned} A(N,\ell,\ell,M_S',M_L) = \sum_{M_{L-}\max\left\{-f\left(\frac{N-M_S'}{2}-1\right),M_L-f\left(\frac{N+M_S'}{2}-1\right)\right\}} ^{\min\left\{f\left(\frac{N-M_S'}{2}-1\right),M_L+f\left(\frac{N+M_S'}{2}-1\right)\right\}} \Bigg\{A\left(\frac{N-M_S'}{2},\ell,\ell,\frac{N-M_S'}{2},M_{L-}\right)\\ \times A\left(\frac{N+M_S'}{2},\ell,\ell,\frac{N+M_S'}{2},M_L-M_{L-}\right)\Bigg\} \end{aligned}

Case 3

$M_S'=N$, $|M_L|\leq f(N-1)$, and $1<N\leq 2\ell+1$:

$$$A(N,\ell,\ell_b,N,M_L) = \sum_{M_{L_I} = \left\lfloor{\frac{M_L-1}{N}+\frac{N+1}{2}}\right\rfloor} ^{\min\{\ell_b,M_L+f(N-2)\}} A(N-1,\ell,M_{L_I}-1,N-1,M_L-M_{L_I})$$$

Case 4

else:

$$$A(N,\ell,\ell_b,M_S',M_L) = 0$$$
source
AtomicLevels.Xu.fFunction
f(n,ℓ)
$$$f(n,\ell)=\begin{cases} \displaystyle\sum_{m=0}^n \ell-m, & n\geq0\\ 0, & n<0 \end{cases}$$$
source
AtomicLevels.xu_termsFunction
xu_terms(ℓ, w, p)

Return all term symbols for the orbital ℓʷ and parity p; the term multiplicity is computed using AtomicLevels.Xu.X.

Examples

julia> AtomicLevels.xu_terms(3, 3, parity(c"3d3"))
17-element Vector{Term}:
²P
²D
²D
²F
²F
²G
²G
²H
²H
²I
²K
²L
⁴S
⁴D
⁴F
⁴G
⁴I
source