Source code for atomsmltr.atoms.generic
"""
atoms
=======================
This module implements the generic ``Atom`` class, that can be used to define
a custom atom species.
Note
----
In general, it is better to create new classes for specific
atomic species, so that they be used by all users. Specifi atomic species
are stored in ``atomsmltr.atoms.collection``
"""
# % IMPORTS
from abc import ABC, abstractmethod
from copy import copy
import scipy.constants as csts
import numpy as np
# % LOCAL IMPORTS
from .transitions import AtomicTransition
from ..utils.infostring import InfoString
# % ABSTRACT CLASSES
[docs]
class Atom(ABC):
"""A generic class to define atomic species.
Parameters
----------
mass : float
the atomic mass in kg
name : str
a name to describe the atom
Example
-------
>>> from atomsmltr.atoms import Atom
>>> from scipy import constants as csts
>>> atom = Atom(mass=4 * csts.m_u, name="Helium")
Note
----
Specific atomic species are implemented in ``atomsmltr.atoms.collection``
"""
def __init__(self, mass: float, name: str):
self.__mass = mass
self.__name = name
self.__transitions = {}
super().__init__()
# - GETTERS AND SETTERS
@property
def mass(self) -> float:
"""float: the atom mass in kg"""
return self.__mass
@property
def mass_au(self) -> float:
"""float: the atom mass in atomic units"""
return self.__mass / csts.m_u
@property
def name(self) -> float:
"""str: the atom name"""
return self.__name
@property
def transitions(self) -> list:
"""list: a list of the atom's transitions"""
return self.__transitions.values()
@property
def trans(self) -> dict:
"""dict: a copy of the atom's transition dictionnary"""
return copy(self.__transitions)
# - RADIATION PRESSURE
[docs]
def get_radiation_pressure(
self,
transition: str, # the transition tag
intensity: float, # the intensity in W/cm^2
mag_field: float, # the amplitude of the magnetic field
polarization: np.ndarray, # projection of laser polarization on (pi, sigma+, sigma-)
detuning: float, # laser detuning
) -> float:
"""Computes the radiation pressure.
Parameters
----------
transition : str
The tag of the considered transition. The transition has to be defined in the atom's
transition list, that can be accessed using the ``list_transitions()`` method.
intensity: float
The laser intensity, in W/m^2
mag_field: float
The *norm* of the magnetic field, in T (scalar).
polarization: ndarray, shape (,3)
Projection of the laser polarization on (pi, sigma+, sigma-)
detuning: float
The laser bare detuning, in rad/s
Returns
-------
F_rad: float
The radiation pressure in SI (scalar)
Notes
-------
Yields the radiation pressure felt by an atom excited on a given transition, by
a laser with given intensity. It takes into account the value of the magnetic field,
the polarization of the laser and its bare detuning.
The computation is based on the ``get_scattering_rate()`` method, implemented in the
``AtomicTransition`` class.
See Also
--------
atomsmltr.atoms.transitions.AtomicTransition.get_scattering_rate()
"""
# parameter check
transition_list = self.list_transitions()
msg = f"There is no transition with tag '{transition}'. Available transitions : {transition_list}"
if transition not in transition_list:
raise KeyError(msg)
# get scattering rate
trans = self.__transitions[transition]
scattering_rate = trans.get_scattering_rate(
intensity, mag_field, polarization, detuning
)
# convert to radiation pressure
k = 2 * csts.pi / trans.wavelength
F_rad = csts.hbar * k * scattering_rate
return F_rad
# - TRANSITIONS MANAGEMENT
[docs]
def get_transitions_copy(self) -> dict:
"""returns a copy of the transition dictionnary
Returns
-------
dict
a dict containing the atom's transitions
"""
return copy(self.__transitions)
[docs]
def add_transition(self, transition: AtomicTransition, tag=None) -> None:
"""adds a transition to the atom transition dict.
Parameters
----------
transition : AtomicTransition
an atomic transition (see ``atomsmltr.atoms.transitions.AtomicTransition``)
tag : str, optional
the tag identifying the transition in the transition dict.
If nothing or ``None`` is given, we will use the ``.tag`` property
of the ``AtomicTransition`` object
See Also
--------
atomsmltr.atoms.transitions.AtomicTransition
"""
# -- parse input
# check transition type
if not isinstance(transition, AtomicTransition):
raise TypeError("`transition` should be an `AtomicTransition`object.")
# if tag is non, use the atomic transition builtin tag
tag = transition.tag if tag is None else tag
# check that not in dictionnary
msg = f"There is already a transition with the tag {tag} in the atom's collection."
assert tag not in self.__transitions, msg
# TODO: other checks ? warning if already same wavelength ?
# -- add to collection
self.__transitions.update({tag: transition})
[docs]
def list_transitions(self) -> list:
"""returns a list of the transition tags (str)
Returns
-------
list of str
list of transition tags
"""
return list(self.__transitions.keys())
[docs]
def rm_transition(self, tag: str) -> None:
"""removes a transition for the atom's transition dict.
Parameters
----------
tag : str
the tag of the transition to remove
"""
del self.__transitions[tag]
# - INFOSTRING
def _gen_infostring_obj(self) -> InfoString:
"""generates an ``InfoString`` object.
Returns
-------
InfoString
an ``InfoString`` object
See also
--------
atomsmltr.utils.infostring.InfoString
"""
info = InfoString(title=self.name)
info.add_section("Parameters")
info.add_element("mass (kg)", f"{self.mass:.2e}")
info.add_element("mass (au)", f"{self.mass_au:.2f}")
info.add_section("Transition list")
for trans_tag in self.list_transitions():
info.add_element(trans_tag)
for trans_tag, trans in self.__transitions.items():
trans_info = trans.gen_infostring_obj()
section_title = f"'{trans_tag}' transition"
info.absorb_section(trans_info, "Parameters", section_title)
return info
[docs]
def gen_infostring_obj(self) -> InfoString:
"""generates an ``InfoString`` object.
Returns
-------
InfoString
an ``InfoString`` object
See also
--------
atomsmltr.utils.infostring.InfoString
"""
return self._gen_infostring_obj()
[docs]
def gen_info_string(self, **kwargs) -> str:
"""generates an info string
Returns
-------
info_string: str
a string with information on the atom
"""
return self.gen_infostring_obj().generate(**kwargs)
[docs]
def print_info(self) -> None:
"""prints the atom infostring"""
print(self.gen_info_string())