|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -import contextlib |
4 | 3 | import logging |
5 | 4 | from abc import ABC |
6 | 5 | from typing import TYPE_CHECKING, Any, ClassVar, Literal, overload |
|
14 | 13 | is_angular_operator_type, |
15 | 14 | ) |
16 | 15 | from rydstate.angular.utils import ( |
| 16 | + InvalidQuantumNumbersError, |
17 | 17 | check_spin_addition_rule, |
18 | 18 | get_possible_quantum_number_values, |
19 | 19 | minus_one_pow, |
|
23 | 23 | from rydstate.species import SpeciesObject |
24 | 24 |
|
25 | 25 | if TYPE_CHECKING: |
26 | | - import juliacall |
27 | 26 | from typing_extensions import Never, Self |
28 | 27 |
|
29 | 28 | from rydstate.angular.angular_matrix_element import AngularMomentumQuantumNumbers, AngularOperatorType |
30 | 29 | from rydstate.angular.angular_state import AngularState |
| 30 | + from rydstate.angular.utils import CouplingScheme |
31 | 31 |
|
32 | 32 | logger = logging.getLogger(__name__) |
33 | 33 |
|
34 | | -CouplingScheme = Literal["LS", "JJ", "FJ", "Dummy"] |
35 | | - |
36 | | - |
37 | | -class InvalidQuantumNumbersError(ValueError): |
38 | | - def __init__(self, ket: AngularKetBase, msg: str = "") -> None: |
39 | | - _msg = f"Invalid quantum numbers for {ket!r}" |
40 | | - if len(msg) > 0: |
41 | | - _msg += f"\n {msg}" |
42 | | - super().__init__(_msg) |
43 | | - |
44 | 34 |
|
45 | 35 | class AngularKetBase(ABC): |
46 | 36 | """Base class for a angular ket (i.e. a simple canonical spin ketstate).""" |
@@ -375,10 +365,6 @@ def calc_reduced_overlap(self, other: AngularKetBase) -> float: |
375 | 365 |
|
376 | 366 | kets = [self, other] |
377 | 367 |
|
378 | | - # Dummy overlaps |
379 | | - if any(isinstance(s, AngularKetDummy) for s in kets): |
380 | | - return int(self == other) |
381 | | - |
382 | 368 | # JJ - FJ overlaps |
383 | 369 | if any(isinstance(s, AngularKetJJ) for s in kets) and any(isinstance(s, AngularKetFJ) for s in kets): |
384 | 370 | jj = next(s for s in kets if isinstance(s, AngularKetJJ)) |
@@ -421,10 +407,6 @@ def calc_reduced_matrix_element( # noqa: C901 |
421 | 407 | if not is_angular_operator_type(operator): |
422 | 408 | raise NotImplementedError(f"calc_reduced_matrix_element is not implemented for operator {operator}.") |
423 | 409 |
|
424 | | - # Dummy matrix elements |
425 | | - if any(isinstance(s, AngularKetDummy) for s in [self, other]): |
426 | | - return 0 |
427 | | - |
428 | 410 | if type(self) is not type(other): |
429 | 411 | return self.to_state().calc_reduced_matrix_element(other.to_state(), operator, kappa) |
430 | 412 | if is_angular_momentum_quantum_number(operator) and operator not in self.quantum_number_names: |
@@ -748,122 +730,3 @@ def sanity_check(self, msgs: list[str] | None = None) -> None: |
748 | 730 | msgs.append(f"{self.f_c=}, {self.j_r=}, {self.f_tot=} don't satisfy spin addition rule.") |
749 | 731 |
|
750 | 732 | super().sanity_check(msgs) |
751 | | - |
752 | | - |
753 | | -class AngularKetDummy(AngularKetBase): |
754 | | - """Dummy spin ket for unknown quantum numbers.""" |
755 | | - |
756 | | - __slots__ = ("name",) |
757 | | - quantum_number_names: ClassVar = ("f_tot",) |
758 | | - coupled_quantum_numbers: ClassVar = {} |
759 | | - coupling_scheme = "Dummy" |
760 | | - |
761 | | - name: str |
762 | | - """Name of the dummy ket.""" |
763 | | - |
764 | | - def __init__( |
765 | | - self, |
766 | | - name: str, |
767 | | - f_tot: float, |
768 | | - m: float | None = None, |
769 | | - ) -> None: |
770 | | - """Initialize the Spin ket.""" |
771 | | - self.name = name |
772 | | - |
773 | | - self.f_tot = f_tot |
774 | | - self.m = m |
775 | | - |
776 | | - super()._post_init() |
777 | | - |
778 | | - def sanity_check(self, msgs: list[str] | None = None) -> None: |
779 | | - """Check that the quantum numbers are valid.""" |
780 | | - msgs = msgs if msgs is not None else [] |
781 | | - |
782 | | - if self.m is not None and not -self.f_tot <= self.m <= self.f_tot: |
783 | | - msgs.append(f"m must be between -f_tot and f_tot, but {self.f_tot=}, {self.m=}") |
784 | | - |
785 | | - if msgs: |
786 | | - msg = "\n ".join(msgs) |
787 | | - raise InvalidQuantumNumbersError(self, msg) |
788 | | - |
789 | | - def __repr__(self) -> str: |
790 | | - args = f"{self.name}, f_tot={self.f_tot}" |
791 | | - if self.m is not None: |
792 | | - args += f", m={self.m}" |
793 | | - return f"{self.__class__.__name__}({args})" |
794 | | - |
795 | | - def __str__(self) -> str: |
796 | | - return self.__repr__().replace("AngularKet", "") |
797 | | - |
798 | | - def __eq__(self, other: object) -> bool: |
799 | | - if not isinstance(other, AngularKetBase): |
800 | | - raise NotImplementedError(f"Cannot compare {self!r} with {other!r}.") |
801 | | - if not isinstance(other, AngularKetDummy): |
802 | | - return False |
803 | | - return self.name == other.name and self.f_tot == other.f_tot and self.m == other.m |
804 | | - |
805 | | - def __hash__(self) -> int: |
806 | | - return hash((self.name, self.f_tot, self.m)) |
807 | | - |
808 | | - |
809 | | -def julia_qn_to_dict(qn: juliacall.AnyValue) -> dict[str, float]: |
810 | | - """Convert MQDT Julia quantum numbers to dict object.""" |
811 | | - if "fjQuantumNumbers" in str(qn): |
812 | | - return dict(s_c=qn.sc, l_c=qn.lc, j_c=qn.Jc, f_c=qn.Fc, l_r=qn.lr, j_r=qn.Jr, f_tot=qn.F) # noqa: C408 |
813 | | - if "jjQuantumNumbers" in str(qn): |
814 | | - return dict(s_c=qn.sc, l_c=qn.lc, j_c=qn.Jc, l_r=qn.lr, j_r=qn.Jr, j_tot=qn.J, f_tot=qn.F) # noqa: C408 |
815 | | - if "lsQuantumNumbers" in str(qn): |
816 | | - return dict(s_c=qn.sc, s_tot=qn.S, l_c=qn.lc, l_r=qn.lr, l_tot=qn.L, j_tot=qn.J, f_tot=qn.F) # noqa: C408 |
817 | | - raise ValueError(f"Unknown MQDT Julia quantum numbers {qn!s}.") |
818 | | - |
819 | | - |
820 | | -def quantum_numbers_to_angular_ket( |
821 | | - species: str | SpeciesObject, |
822 | | - s_c: float | None = None, |
823 | | - l_c: int = 0, |
824 | | - j_c: float | None = None, |
825 | | - f_c: float | None = None, |
826 | | - s_r: float = 0.5, |
827 | | - l_r: int | None = None, |
828 | | - j_r: float | None = None, |
829 | | - s_tot: float | None = None, |
830 | | - l_tot: int | None = None, |
831 | | - j_tot: float | None = None, |
832 | | - f_tot: float | None = None, |
833 | | - m: float | None = None, |
834 | | -) -> AngularKetBase: |
835 | | - r"""Return an AngularKet object in the corresponding coupling scheme from the given quantum numbers. |
836 | | -
|
837 | | - Args: |
838 | | - species: Atomic species. |
839 | | - s_c: Spin quantum number of the core electron (0 for Alkali, 0.5 for divalent atoms). |
840 | | - l_c: Orbital angular momentum quantum number of the core electron. |
841 | | - j_c: Total angular momentum quantum number of the core electron. |
842 | | - f_c: Total angular momentum quantum number of the core (core electron + nucleus). |
843 | | - s_r: Spin quantum number of the rydberg electron (always 0.5). |
844 | | - l_r: Orbital angular momentum quantum number of the rydberg electron. |
845 | | - j_r: Total angular momentum quantum number of the rydberg electron. |
846 | | - s_tot: Total spin quantum number of all electrons. |
847 | | - l_tot: Total orbital angular momentum quantum number of all electrons. |
848 | | - j_tot: Total angular momentum quantum number of all electrons. |
849 | | - f_tot: Total angular momentum quantum number of the atom (rydberg electron + core). |
850 | | - m: Total magnetic quantum number. |
851 | | - Optional, only needed for concrete angular matrix elements. |
852 | | -
|
853 | | - """ |
854 | | - with contextlib.suppress(InvalidQuantumNumbersError, ValueError): |
855 | | - return AngularKetLS( |
856 | | - s_c=s_c, l_c=l_c, s_r=s_r, l_r=l_r, s_tot=s_tot, l_tot=l_tot, j_tot=j_tot, f_tot=f_tot, m=m, species=species |
857 | | - ) |
858 | | - |
859 | | - with contextlib.suppress(InvalidQuantumNumbersError, ValueError): |
860 | | - return AngularKetJJ( |
861 | | - s_c=s_c, l_c=l_c, j_c=j_c, s_r=s_r, l_r=l_r, j_r=j_r, j_tot=j_tot, f_tot=f_tot, m=m, species=species |
862 | | - ) |
863 | | - |
864 | | - with contextlib.suppress(InvalidQuantumNumbersError, ValueError): |
865 | | - return AngularKetFJ( |
866 | | - s_c=s_c, l_c=l_c, j_c=j_c, f_c=f_c, s_r=s_r, l_r=l_r, j_r=j_r, f_tot=f_tot, m=m, species=species |
867 | | - ) |
868 | | - |
869 | | - raise ValueError("Invalid combination of angular quantum numbers provided.") |
0 commit comments