The starkr package is designed to calculate the Stark matrix and Stark maps for Rubidium-85. The code relies heavily on techniques and algorithms used by [@Zimmerman1979] in their paper analyzing the Stark structure of alkali-metal atoms. The code described below is broken up in to several sections:

library(starkr)
library(dplyr)
library(ggplot2)

Components of the Stark matrix element

All of the functions that calcuate the underlying pieces of the Stark matrix element may be used independently of the Stark matrix element calculation.

Quantum Defect

quantum_defect() calculates the quantum defect of an arbitrary (n, l, j) state of Rubidium-85. The quantum defect is calculated using a modified version of equation (16.19) from [insert Gallagher Rydberg Atoms reference] pg. 351.

$$\delta_{n, l, j} = \delta_{0} + \frac{\delta_{2}}{(n - \delta_{0})^{2}}$$

The parameters $\delta_{0}$ and $\delta_{2}$ are experimentally measured values from the following papers [insert Refereneces].

Clebsch-Gordan Coefficients and Wigner-3j Symbols

clebsch_gordan() calculates the Clebsch-Gordan coefficient for an arbitrary selection of quantum numbers j~1~, j~2~, m~1~, m~2~, j, and m~j~. The conditions that must be met for a Clebsch-Gordan coefficient are that $m_{1} + m_{2} = m_{j}$.

There are two functions that calculate the Clebsch-Gordan coefficient within starkr. The first is clebsch_gordan() which uses an analytic form which can be found in Edmonds [insert reference] or Lindgren and Morrison [insert Reference]. The second is clebsch_gordan2() which uses an analytic form found in Cromwell's Group Theory of Physics [insert Reference].

wigner_3j() is provided for completeness and is not actually used in the calculation of the Stark matrix element. It is calculated using the Clebsch-Gordan coefficient.

[Insert Examples]

Spherical Matrix Element

sphere_mat_element() calculates the spherical matrix element $$ based on the form given by @Zimmerman1979.

Radial Matrix Element

radial_matrix_element() calculates the radial matrix element $$ for arbitrary quantum numbers n, n', l, and l'. The calculation is done using a Numerov algorithm as used by @Zimmerman1979 (see Appendix A). This calculation uses the square-root scaling done by @Bhatti1981 where $\xi = \sqrt{r}$ and $\Psi = r^{3/4} R(r)$.

Calculating and Building the Stark Matrix

Computing the elements of the Stark matrix and building said matrix requires a few additional functions to work together. First, we have to compute the individual elements of the Stark matrix. Then we have to put all of those elements in to the appropriate spot in the matrix.

Stark Matrix Elements

The elements of the Stark matrix are calculated using stark_matrix_elem(). stark_matrix_elem() is based on equation 10 from @Zimmerman1979. It requires the full $(n, l, j, m_{j})$ of quantum numbers for both the initial and final states. Equation 10 from @Zimmerman1979 is reproduced below:

$$$$ $$= \delta(m_{j}, m_{j}') \delta(l, l'\pm 1) F$$ $$\times \sum_{m_{l} = m_{j} \pm \frac{1}{2}} $$

where W and W' are the energies of the initial and final states respectively and F is the applied electric field. The energy is $W = -1/2(n - \delta)^{2}$ where $\delta$ is the quantum defect for state $(n, l, j, m_{j})$. The Stark matrix element will be equal to zero unless it fulfills the requirement that $m_{j} = m_{j}'$ and $l = l' \pm 1$.

Building the Stark Matrix

There are still a few pieces left before you will be able to build the Stark matrix. To properly calculate the Stark map for a given set of states, you need to include a large number of states of both higher and lower energies. The suggestion from @Zimmerman1979 is to include the full manifolds for at least $n \pm 4$. To build the list of states you plan on including in the Stark matrix, the function state_list() can be used. state_list() creates a matrix with columns n, l, and j and these columns contain all of the possible n, l, j combinations for a given $m_{j}$. For example, if looking at the states for the $n = 3$, $m_{j} = \frac{1}{2}$ manifold you would get:

starkr::state_list(3, 3, 1/2, 0, 0)

There are some additional paramters in state_list() that allow for the addition of lower angular momentum states. For example, if n_add_min is set to 2, then all of the low angular momentum states ($l < 6$) would be included for nmin - 1 and nmin - 2. n_add_max is treated similarly, but on the higher n side. These additional states allow for the states that have the highest impact on the Stark map without adding too much computational load by inclding the full manifolds at those n's.

Note: Because the different $m_{j}$ states do not interact, you will need to compute the state list and Stark matrix separately for each $m_{j}$.

Once the state matrix has been calculated, the Stark matrix can be constructed. For building the Stark matrix, you may find it useful to save the n, l, and j columns of the state matrix into their own vectors.

states <- starkr::state_list(15, 15, 1/2, 0, 0)
n <- states[, 1]
l <- states[, 2]
j <- states[, 3]
m_j <- 1/2

Now you are ready to construct the Stark matrix!

mat <- starkr::stark_matrix(n, l, j, m_j)

Note that stark_matrix() will print the row that is currently being processed with the message:

# Current row being processed: [i]

where [i] is the row number.

The output of stark_matrix() will look like the following:

mat[1:4, 1:4]

where element [i, k] is the result of stark_matrix_element(): $$.

Diagonalizing the Stark Matrix

To diagonalize the Stark matrix, you will need a few additional functions. The total matrix need find the eigenenergies and eigenstates of the system is a matrix of zero field energies summed with the Stark matrix. The zero field energy matrix is calculated using zero_field_energy_mat(). This function takes the vector of n, l, and j values used in stark_matrix() and returns a diagonal matrix with elements:

$$W_{n, l, j} = \frac{1}{2(n - \delta_{n, l, j})^{2}}$$

zero_energy_mat <- starkr::zero_field_energy_mat(n, l, j)
zero_energy_mat[1:4, 1:4]

stark_eigen() diagonalizes the combined Stark matrix and zero field energy matrix at a series of electric fields. The user must provide a field vector with units of V/cm over which the matrix will be diagonalized. This function returns a matrix of energy eigenvalues in which the rows are the different field steps and each columns corresponds to a different starting state.

field <- seq(0, 4, by = 0.5)

stark_map <- starkr::stark_eigen(mat, zero_energy_mat, field)
stark_map[1:4, 1:4]

Tidying the Stark Map

The output from stark_eigen() tends to be pretty messy and it can be hard to determine which column corresponds to what zero field energy. To fix this, you can use tidy_stark_energy() to put your eigen energies in to a form that is easy to manipulate and plot.

First, you will need to use zero_field_energy_df() to create a data frame with all of the zero field energies. This function is similar to the matrix form in the previous section.

zero_df <- starkr::zero_field_energy_df(n, l, j, m_j)
zero_df

tidy_stark_energy() takes the zero field energy data frame and the Stark energy matrix as starting arguments. The field vector must be the same as used in stark_eigen(). tidy_stark_energy() takes the zero field energy data frame and arranges the rows to match the order of the columns in the Stark energy matrix. It then outputs a tidy data frame with all of the energy and field values and matching $E_{0}$, $n$, $l$, $j$, $m_{j}$, and a string representation of the state.

tidy_df <- starkr::tidy_stark_energy(zero_df, stark_map, field)
tidy_df

Once the data has been put in to a tidy format, it is very simple to plot it.

tidy_df %>%
  filter(l > 4) %>%
  ggplot(aes(x = Field, y = E, group = state)) +
  geom_line()

Now you have a Stark map!

Radial Matrix Elements of Stark Eigenstates

Now that you have created a Stark matrix and Stark map, you can use that matrix to calculate the radial matrix element for some initial pure zero-field state and a Stark state at arbitrary field. stark_radial_mat_elem() takes the Stark matrix you made earlier, an initial state represented by a character, and a Stark state also represented by a character and related to its equivalent zero-field state. You will also need to provide the desired field strength, the minimum and maximum n that matches your Stark matrix along with the additional low angular momentum states included in your Stark matrix.

stark_radial_mat_elem(mat, "5,1,1.5,1.5", "15,1,1.5,0.5", field = 10, n_min = 15, n_max = 15, n_add_min = 0, n_add_max = 0)


bgrich/starkr documentation built on May 12, 2019, 8:21 p.m.