Support Files

The following modules and their functions are used extensively throughout the chinook package.

Rotations

Created on Mon Oct 1 20:04:24 2018

@author: rday

Various functions relevant to rotations

rotation_lib.Euler(rotation)

Euler rotation angle generation, Z-Y-Z convention, as defined for a user-defined rotation matrix. Special case for B = +/- Z*pi where conventional approach doesn’t work due to division by zero, then Euler_A is zero and Euler_y is arctan(R10,R00)

args:

  • rotation: numpy array of 3x3 float (rotation matrix)

OR tuple/list of vector and angle (numpy array of 3 float, float) respectively

return:

  • Euler_A, Euler_B, Euler_y: float, Euler angles associated with

the given rotation.

***

rotation_lib.Euler_to_R(Euler_A, Euler_B, Euler_y)

Inverse of Euler, generate a rotation matrix from the Euler angles A,B,y with the same conventiona as in Euler.

args:

  • Euler_A, Euler_B, Euler_y: float

return:

  • numpy array of 3x3 float

***

rotation_lib.Rodrigues_Rmat(nvec, theta)

Following Rodrigues theorem for rotations, define a rotation matrix which corresponds to the rotation about a vector nvec by the angle theta, in radians. Works in pre-multiplication order (i.e. v’ = R.v)

args:

  • nvec: numpy array len 3 axis of rotation
  • theta: float radian angle of rotation counter clockwise for theta>0

return:

  • Rmat: numpy array 3x3 of float rotation matrix

***

rotation_lib.rot_vector(Rmatrix)

Inverse to Rodrigues_Rmat, take rotation matrix as input and return the angle-axis convention rotations corresponding to this rotation matrix.

args:

  • Rmatrix: numpy array of 3x3 float, rotation matrix

return:

  • nvec: numpy array of 3 float, rotation axis
  • theta: float, rotation angle in float

***

rotation_lib.rotate_v1v2(v1, v2)

This generates the rotation matrix for PRE-multiplication rotation: or written another way, defining R s.t. R.v1 = v2. This rotation will rotate the vector v1 onto the vector v2.

args:

  • v1: numpy array len 3 of float, input vector
  • v2: numpy array len 3 of float, vector to rotate into

return:

  • Rmat: numpy array of 3x3 float, rotation matrix

***

Wigner Matrices

wigner.Wd_denominator(j, m, mp, sp)

Small function for computing the denominator in the s-summation, one step in defining the matrix elements of Wigner’s small d-matrix

args:

  • j, m, mp: integer (or half-integer) angular momentum

quantum numbers

  • s: int, the index of the summation

return:

  • int, product of factorials

***

wigner.WignerD(l, Euler_A, Euler_B, Euler_y)

Full matrix representation of Wigner’s Big D matrix relating the rotation of states within the subspace of the angular momentum l by the Euler rotation Z”(A)-Y’(B)-Z(y)

args:

  • l: int (or half integer) angular momentum
  • Euler_A, Euler_B, Euler_y: float z-y-z Euler angles defining

the rotation

return:

  • Dmat: 2j+1 x 2j+1 numpy array of complex float

***

wigner.big_D_element(j, mp, m, Euler_A, Euler_B, Euler_y)

Combining Wigner’s small d matrix with the other two rotations, this defines Wigner’s big D matrix, which defines the projection of an angular momentum state onto the other azimuthal projections of this angular momentum. Wigner defined these matrices in the convention of a set of z-y-z Euler angles, passed here along with the relevant quantum numbers:

args:

  • j, mp, m: integer (half-integer) angular momentum quantum numbers
  • Euler_A, Euler_B, Euler_y: float z-y-z Euler angles defining

the rotation

return:

  • complex float corresponding to the [mp,m] matrix element

***

wigner.fact(N)

Recursive factorial function for non-negative integers.

args:

  • N: int, or int-like float

return:

  • factorial of N

***

wigner.s_lims(j, m, mp)

Limits for summation in definition of Wigner’s little d-matrix

args:

  • j: int,(or half-integer) total angular momentum quantum number
  • m: int, (or half-integer) initial azimuthal angular momentum quantum number
  • mp: int, (or half-integer) final azimuthal angular momentum

quantum number coupled to by rotation

return:

  • list of int, viable candidates which result in well-defined factorials in

summation

***

wigner.small_D(j, mp, m, Euler_B)
Wigner’s little d matrix, defined as _
j (-1)^(mp-m+s) 2j+m-mp-2s mp-m+2s
d (B) = sqrt((j+mp)!(j-mp)!(j+m)!(j-m)!) > —————————– cos(B/2) sin(B/2)
mp,m /_s (j+m-s)!s!(mp-m+s)!(j-mp-s)!

where the sum over s includes all integers for which the factorial arguments in the denominator are non-negative. The limits for this summation are defined by s_lims(j,m,mp).

args:

  • j, mp ,**m** – integer (or half-integer) angular momentum

quantum numbers for the orbital angular momentum, and its azimuthal projections which are related by the Wigner D matrix during the rotation

  • Euler_B: float, angle of rotation in radians, for the y-rotation

return:

  • float representing the matrix element of Wigner’s small d-matrix

***

Spherical Harmonics

Ylm.GramSchmidt(a, b)

Simple orthogonalization of two vectors, returns orthonormalized vector

args:

  • a, b: numpy array of same length

returns:

  • GS_a: numpy array of same size, orthonormalized to the b vector

***

Ylm.Y(l, m, theta, phi)

Spherical harmonics, defined here up to l = 4. This allows for photoemission from initial states up to and including f-electrons (final states can be d- or g- like). Can be vectorized with numpy.vectorize() to allow array-like input

args:

  • l: int orbital angular momentum, up to l=4 supported
  • m: int, azimuthal angular momentum |m|<=l
  • theta: float, angle in spherical coordinates, radian measured from the z-axis [0,pi]
  • phi: float, angle in spherical coordinates, radian measured from the x-axis [0,2pi]

return:

  • complex float, value of spherical harmonic evaluated at theta,phi
Ylm.Yproj(basis)

Define the unitary transformation rotating the basis of different inequivalent atoms in the basis to the basis of spherical harmonics for sake of defining L.S operator in basis of user

29/09/2018 added reference to the spin character ‘sp’ to handle rotated systems effectively

args:

  • basis: list of orbital objects

return:

  • dictionary of matrices for the different atoms and l-shells–keys are tuples of (atom,l)

***

Ylm.binom(a, b)

Binomial coefficient for ‘a choose b’

args:

  • a: int, positive
  • b: int, positive

return:

  • float, binomial coefficient

***

Ylm.fillin(M, l, Dmat=None)

If only using a reduced subset of an orbital shell (for example, only t2g states in d-shell), need to fill in the rest of the projection matrix with some defaults

args:

  • M: numpy array of (2l+1)x(2l+1) complex float
  • l: int
  • Dmat: numpy array of (2l+1)x(2l+1) complex float

return:

  • M: numpy arrayof (2l+1)x(2l+1) complex float

***

Ylm.gaunt(l, m, dl, dm)

I prefer to avoid using the sympy library where possible, for speed reasons. These are the explicitly defined Gaunt coefficients required for dipole-allowed transitions (dl = +/-1) for arbitrary m,l and dm These have been tested against the sympy package to confirm numerical accuracy for all l,m possible up to l=5. This function is equivalent, for the subset of dm, dl allowed to sympy.physics.wigner.gaunt(l,1,l+dl,m,dm,-(m+dm))

args:

  • l: int orbital angular momentum quantum number
  • m: int azimuthal angular momentum quantum number
  • dl: int change in l (+/-1)
  • dm: int change in azimuthal angular momentum (-1,0,1)

return:

  • float Gaunt coefficient

***

Ylm.laguerre(x, l, j)

Laguerre polynomial of order l, degree j, evaluated over x

args:

  • x: float or numpy array of float, input
  • l: int, order of polynomial
  • j: int, degree of polynomial

return:

  • laguerre_output: float or numpy array of float, shape as input x

***

Ylm.value_one(theta, phi)

Flexible generation of the number 1.0, in either float or array format

args:

  • theta: float or numpy array of float
  • phi: float or numpy array of float

return:

out: float or numpy array of float, evaluated to 1.0, of same shape and type as theta, phi

***