Quantum mechanics and nuclear transitions
Nexus provides a couple of functions to calculate basic quantum mechanical and nuclear parameters. Here a few basic functionalities are shown.
Quantum mechanics
Clebsh-Gordon coefficients
import nexus as nx
print(nx.ClebshGordon(1/2, 1, -1/2, 1, 3/2, 1/2))
0.5773502691896257
.
Three J Symbols
import nexus as nx
print(nx.ThreeJSymbol(1/2, 1, 3/2, -1/2, 1, -1/2))
0.28867513459481287
.
V coefficient
import nexus as nx
print(nx.VCoefficient(1/2, 1, 3/2, -1/2, 1, -1/2))
0.28867513459481287
.
Wigner matrices
import nexus as nx
print(nx.SmallWignerDmatrix(1, 1, 1, nx.pi/2.5))
print(nx.WignerDmatrix(1, 1, 1, nx.pi/2.5, nx.pi/1.5, nx.pi/2))
0.654508497187474
(-0.23776412907378872-0.07725424859373696j)
Vector Spherical Harmonics
These functions calculate the vector spherical harmonics in the polarization base of \(\sigma\) and \(\pi\) polarization for a rotation of the quantization axis by some Euler angles.
They return a list of size \(2*L+1\), where \(L\) is the photon angular momentum of the transition. Each entry has a sigma
and a pi
component
import nexus as nx
# E1 transition, L=1, lambda=1
# obtain 2*L+1 vector components
VSH = nx.VecSpherHarmPolarization(1,1)
print(VSH[0].sigma) # l = -1
print(VSH[0].pi)
print(VSH[1].sigma) # l = 0
print(VSH[1].pi)
print(VSH[2].sigma) # l = +1
print(VSH[2].pi)
output is
(Vector Spherical Harmonics in polarization base - sigma: (-0.24430125595145996-0j) - pi 0.24430125595145996j, Vector Spherical Harmonics in polarization base - sigma: (-0-0j) - pi -0j, Vector Spherical Harmonics in polarization base - sigma: (-0.24430125595145996-0j) - pi -0.24430125595145996j)
(-0.24430125595145996-0j)
0.24430125595145996j
(-0-0j)
-0j
(-0.24430125595145996-0j)
-0.24430125595145996j
# with Euler angles
euler = nx.Eulerangles(nx.pi/2, nx.pi/2, nx.pi/2)
vsh = nx.VecSpherHarmPolarization(1,0,euler)
print(vsh)
print(vsh[0].sigma)
print(vsh[0].pi)
print(vsh[1].sigma)
print(vsh[1].pi)
print(vsh[2].sigma)
print(vsh[2].pi)
output is
(Vector Spherical Harmonics in polarization base - sigma: (2.712288793021544e-17-1.4959137556431694e-17j) - pi (-4.487741266929507e-17-0.24430125595145996j), Vector Spherical Harmonics in polarization base - sigma: (-2.1155415213710417e-17-0.34549414947133555j) - pi 2.1155415213710417e-17j, Vector Spherical Harmonics in polarization base - sigma: (2.712288793021544e-17+1.4959137556431687e-17j) - pi (-1.4959137556431694e-17+0.24430125595145996j))
(2.712288793021544e-17-1.4959137556431694e-17j)
(-4.487741266929507e-17-0.24430125595145996j)
(-2.1155415213710417e-17-0.34549414947133555j)
2.1155415213710417e-17j
(2.712288793021544e-17+1.4959137556431687e-17j)
(-1.4959137556431694e-17+0.24430125595145996j)
Nuclear transitions
Nexus also provides functions to directly calculate the nuclear Hamiltonians and the nuclear transitions.
In order to do so, you need to specify a set of hyperfine parameters via the BareHyperfine
class.
This class does not support any distributions but you can specify the isotropic
parameter.
import nexus as nx
hyperfine = nx.BareHyperfine(magnetic_field = 33,
isotropic = False)
This class is then passed to the function to calculate nuclear transition properties.
Hamiltonian
The ground and excited state Hamiltonians can be directly calculated. The isotropic
parameter has no influence on the Hamiltonian.
With a spin of \(J\) one obtains a square matrix of dimension \(2J+1\). The matrix elements range from \(-J,...,J\).
# returns the ground state Hamiltonian
hamiltonian = nx.HamiltonianGroundState(hyperfine, nx.lib.moessbauer.Fe57)
print(hamiltonian)
# returns the excited state Hamiltonian
hamiltonian = nx.HamiltonianExcitedState(hyperfine, nx.lib.moessbauer.Fe57)
print(hamiltonian)
and the output is
[[ 20.20721718+0.j 0. -0.j]
[ 0. +0.j -20.20721718+0.j]]
[[-34.61800398+0.j 0. -0.j 0. -0.j 0. -0.j]
[ 0. +0.j -11.53933466+0.j 0. -0.j 0. -0.j]
[ 0. +0.j 0. +0.j 11.53933466+0.j 0. -0.j]
[ 0. +0.j 0. +0.j 0. +0.j 34.61800398+0.j]]
The matrix entries give the detuning in units of the linewidth \(\Gamma\) for the different spin states in spin basis with quantization axis along the k-vector.
Because the magnetic field points along the quantization axis, the Hamiltonian is already diagonal. We can directly read the energy detuning for the different spin configurations. In the ground state the \(m=-1/2\) state is shifted by \(20.2 \Gamma\) and the \(m=1/2\) state by \(-20.2 \Gamma\). For the excited state the shifts are: \(m=-3/2\) by \(-34.6 \Gamma\), \(m=-1/2\) by \(-11.5 \Gamma\), \(m=1/2\) by \(11.5 \Gamma\), and \(m=3/2\) by \(34.6 \Gamma\).
If the matrix is not diagonal, the situation is a bit more complicated
hyperfine = nx.BareHyperfine(
magnetic_field = 33,
magnetic_theta = nx.DegToRad(90))
hamiltonian = nx.HamiltonianGroundState(hyperfine, nx.lib.moessbauer.Fe57)
print(hamiltonian)
hamiltonian = nx.HamiltonianExcitedState(hyperfine, nx.lib.moessbauer.Fe57)
print(hamiltonian)
to obtain
[[ 20.19962365+0.j 0.55392294-0.j]
[ 0.55392294+0.j -20.19962365+0.j]]
[[-34.60499512+0.j -0.54787847-0.j 0. -0.j 0. -0.j]
[ -0.54787847+0.j -11.53499837+0.j -0.63263557-0.j 0. -0.j]
[ 0. +0.j -0.63263557+0.j 11.53499837+0.j -0.54787847-0.j]
[ 0. +0.j 0. +0.j -0.54787847+0.j 34.60499512+0.j]]
these matrices have to be diagonalized.
Diagonalization
To diagonalize a Hermitian matrix use the DiagonalizeHermitian()
function.
import nexus as nx
hyperfine = nx.BareHyperfine(
magnetic_field = 33,
magnetic_theta = nx.DegToRad(90))
hamiltonian = nx.HamiltonianGroundState(hyperfine, nx.lib.moessbauer.Fe57)
eigen_system = nx.DiagonalizeHermitian(hamiltonian)
It will return an Eigensystem
class object which holds the eigenvectors and the eigenvalues.
# list of eigenvalues
print(eigen_system.eigenvalues)
# list of corresponding eigenvectors
for vector in eigen_system.eigenvectors:
print(vector)
with the output
[[-34.61800398]
[-11.53933466]
[ 11.53933466]
[ 34.61800398]]
[-9.99718176e-01+0.j -2.37373737e-02-0.j 3.25407171e-04+0.j
2.57549638e-06-0.j]
[-2.37373737e-02+0.j 9.99342428e-01-0.j -2.74069827e-02+0.j
-3.25407171e-04-0.j]
[-3.25407171e-04+0.j 2.74069827e-02-0.j 9.99342428e-01+0.j
2.37373737e-02-0.j]
[-2.57549638e-06+0.j 3.25407171e-04-0.j 2.37373737e-02+0.j
-9.99718176e-01-0.j]
So we obtain four transitions with the same eigenvalues (energy detunings) as in the previously already diagonal case.
Hyperfine Transitions
To obtain the transitions under the action of hyperfine interactions you can use the function HyperfineTransitions()
.
The function will return a Transitions
class object.
It is a vector of Transition
objects.
Each Transition
object has the attributes
energy_detuning
: Energy detuning from the unsplit nuclear transition energy in units of linewidth.transition_polarisation_matrix
: Polarization dependent 2x2 complex transition matrix.weight
: Relative weight of the transition in a material.
We will calculate all transitions of the hyperfine site
import nexus as nx
hyperfine = nx.BareHyperfine(
weight = 1,
magnetic_field = 33,
magnetic_theta = nx.DegToRad(90))
# returns a Transitions object
nuclear_transitions = nx.HyperfineTransitions(hyperfine, nx.lib.moessbauer.Fe57)
# a single transition
print(nuclear_transitions[0])
# energy detuning in units of Gamma
print("\ndetuning {}".format(nuclear_transitions[0].energy_detuning))
# a 2x2 matrix with the polarization components
print("\npolarisation matrix\n{}".format(nuclear_transitions[0].transition_polarisation_matrix))
# number of all transitions in the nucleus
print("\nnumber of transitions: {}".format(len(nuclear_transitions)))
# all transitions
for trans in nuclear_transitions:
print(trans.energy_detuning)
and we get
weight = 1.0
energy_detuning = 8.667882519568264
transition_polarisation_matrix:
[[ 0.125 +0.j -0. +0.12495303j]
[-0. -0.12495303j 0.12490607+0.j ]]
detuning 8.667882519568264
polarisation matrix
[[ 0.125 +0.j -0. +0.12495303j]
[-0. -0.12495303j 0.12490607+0.j ]]
number of transitions: 6
8.667882519568264
31.746551839648678
54.82522115972908
-54.82522115972908
-31.74655183964868
-8.66788251956827
Please have a look at the API Reference for more information.