Atoms & Transitions#

In this example we illustrate the use of the atomsmltr.atoms subpackage.

Work with existing atoms#

Some atomic species are already implemented and defined ine the atomsmltr.atoms.collection module. They can be directly imported from the atoms subpackage :

from atomsmltr.atoms import Ytterbium, Strontium

Then, it is straightforward to initiate those atoms:

yb = Ytterbium()
yb.print_info()
─────────────
| Ytterbium |
─────────────
. Parameters :
  ├── mass (kg) : 2.89e-25
  └── mass (au) : 173.94

. Transition list :
  ├── main
  └── intercombination

. 'main' transition :
  ├── λ : 398.91 nm
  ├── Γ : 2π × 2.89e+07 Hz
  ├── Isat : 59.51 mw/cm²
  └── lande factor g : 1.035

. 'intercombination' transition :
  ├── λ : 555.80 nm
  ├── Γ : 2π × 1.82e+05 Hz
  ├── Isat : 0.14 mw/cm²
  └── lande factor g : 1.493
sr = Strontium()
sr.print_info()
─────────────
| Strontium |
─────────────
. Parameters :
  ├── mass (kg) : 1.46e-25
  └── mass (au) : 88.00

. Transition list :
  ├── main
  └── intercombination

. 'main' transition :
  ├── λ : 460.86 nm
  ├── Γ : 2π × 3.20e+07 Hz
  ├── Isat : 42.73 mw/cm²
  └── lande factor g : 1.0

. 'intercombination' transition :
  ├── λ : 689.45 nm
  ├── Γ : 2π × 7.46e+03 Hz
  ├── Isat : 0.00 mw/cm²
  └── lande factor g : 1.5

Atoms properties#

The Atom object carries some atomic physical properties, as well as a list of transitions.

from atomsmltr.atoms import Ytterbium

yb = Ytterbium()

# - some physical properties
print(f"Ytterbium mass : {yb.mass :.3g} kg")
print(f"Ytterbium mass : {yb.mass_au :.3g} a.u.")

# - implemented transitions
print(f"Transitions : {yb.list_transitions()}")
Ytterbium mass : 2.89e-25 kg
Ytterbium mass : 174 a.u.
Transitions : ['main', 'intercombination']

the associated transitions can be retrieved using the .trans property

main = yb.trans["main"]
main.print_info()
────────
| main |
────────
. Parameters :
  ├── λ : 398.91 nm
  ├── Γ : 2π × 2.89e+07 Hz
  ├── Isat : 59.51 mw/cm²
  └── lande factor g : 1.035

Atoms methods#

It is possible to compute the radiation pressure felt by an atom on one of its transitions using the .get_radiation_pressure() method :

from atomsmltr.atoms import Ytterbium
import numpy as np

# - settings
laser_intensity = 1e4  # W/m^2
laser_detuning = 2 * np.pi * 1e6  # rad/s
mag_field = 1e-4  # T
polarization = np.array((0, 0, 1))  # (pi, sigma+, sigma-)

# - compute
f = Ytterbium().get_radiation_pressure(
    transition="main",
    intensity=laser_intensity,
    mag_field=mag_field,
    polarization=polarization,
    detuning=laser_detuning,
)

print(f"radiation pressure = {f:.3g} N")
radiation pressure = 1.42e-19 N

Transitions properties & methods#

The Transition object carries information on an atomic transition:

from atomsmltr.atoms import Strontium

# - get strontium main transition
main = Strontium().trans["main"]

# - access some properties
print(f"vacuum wavelength : {main.wavelength :.3g} m")
print(f"natural linewidth : {main.Gamma :.3g} rad/s")
print(f"saturation intensity : {main.Isat :.3g} W/m^2")
print(f"saturation intensity : {main.Isat_mW_per_cm2 :.3g} mW/cm^2")
print(f"Lande g factor : {main.lande_factor :.3f}")
print(f"wavenumber : {main.k :.3g} m^-1")
vacuum wavelength : 4.61e-07 m
natural linewidth : 2.01e+08 rad/s
saturation intensity : 427 W/m^2
saturation intensity : 42.7 mW/cm^2
Lande g factor : 1.000
wavenumber : 1.36e+07 m^-1

and some useful methods too:

# - saturation parameter
intensity = 0.5 * main.Isat  # W/m^2
detuning = 0.5 * main.Gamma  # rad/s
s = main.get_saturation_parameter(intensity, detuning)

print(f"{s=}")

# - scattering rate
intensity = 0.5 * main.Isat  # W/m^2
detuning = 0.5 * main.Gamma  # rad/s
mag_field = 1e-4  # T
polarization = np.array((0, 0, 1))  # (pi, sigma+, sigma-)

rate = main.get_scattering_rate(intensity, mag_field, polarization, detuning)
print(f"scattering rate = {rate:.3g} s^-1")
s=0.25
scattering rate = 1.87e+07 s^-1

Define custom atoms and transitions#

We strongly advise users that would need atoms or transitions that are not implemented to write dedicated classes and include them in the atoms.collection module.

This being said, atoms and transitions can also be declared on the fly:

from scipy import constants as csts
from atomsmltr.atoms import Atom, J0J1Transition

# - create an ytterbium atom from scratch

# create the atom
yb174 = Atom(mass=174 * csts.m_u, name="Yb174")

# crate a transition
yb_main = J0J1Transition(
    wavelength=399e-9, Gamma=2 * csts.pi * 30e6, lande_factor=1.5, tag="main"
)

# add main to the atom transition collection
yb174.add_transition(yb_main)

# check what we have done
yb174.print_info()
─────────
| Yb174 |
─────────
. Parameters :
  ├── mass (kg) : 2.89e-25
  └── mass (au) : 174.00

. Transition list :
  └── main

. 'main' transition :
  ├── λ : 399.00 nm
  ├── Γ : 2π × 3.00e+07 Hz
  ├── Isat : 61.73 mw/cm²
  └── lande factor g : 1.5