LCOV - code coverage report
Current view: top level - tests - test_green_tensor.py (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 65 100.0 %
Date: 2026-03-03 11:15:30 Functions: 4 4 100.0 %

          Line data    Source code
       1             : # SPDX-FileCopyrightText: 2024 PairInteraction Developers
       2             : # SPDX-License-Identifier: LGPL-3.0-or-later
       3             : 
       4           1 : from __future__ import annotations
       5             : 
       6           1 : from typing import TYPE_CHECKING
       7             : 
       8           1 : import numpy as np
       9           1 : import pytest
      10           1 : from pairinteraction import ureg
      11           1 : from pairinteraction.green_tensor import GreenTensorFreeSpace
      12           1 : from pairinteraction.green_tensor.green_tensor_cavity import GreenTensorCavity
      13           1 : from pairinteraction.green_tensor.green_tensor_surface import GreenTensorSurface
      14             : 
      15             : if TYPE_CHECKING:
      16             :     from pairinteraction.green_tensor.green_tensor_base import GreenTensorBase
      17             :     from pairinteraction.units import NDArray
      18             : 
      19             :     from .utils import PairinteractionModule
      20             : 
      21           1 : DISTANCE_VECTOR_MUM_LIST = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 3.5]]
      22             : 
      23             : 
      24           1 : @pytest.mark.parametrize("distance_vector_mum", DISTANCE_VECTOR_MUM_LIST)
      25           1 : def test_static_green_tensor(distance_vector_mum: list[float]) -> None:
      26           1 :     gt_reference = reference_green_tensor_vacuum(distance_vector_mum)
      27             : 
      28             :     gt: GreenTensorBase
      29           1 :     gt = GreenTensorFreeSpace([0, 0, 0], distance_vector_mum, unit="micrometer", static_limit=True)
      30           1 :     gt_dipole_dipole = gt.get(1, 1, transition_energy=0, scaled=True)
      31           1 :     np.testing.assert_allclose(gt_dipole_dipole.m, gt_reference)
      32             : 
      33           1 :     gt = GreenTensorSurface([0, 0, 0], distance_vector_mum, z=1000, unit="micrometer", static_limit=True)
      34           1 :     gt_dipole_dipole = gt.get(1, 1, transition_energy=0, scaled=True)
      35           1 :     np.testing.assert_allclose(gt_dipole_dipole.m, gt_reference, rtol=1e-6, atol=1e-16)
      36             : 
      37           1 :     gt = GreenTensorCavity([0, 0, 0], distance_vector_mum, z1=-1000, z2=1000, unit="micrometer", static_limit=True)
      38           1 :     gt_dipole_dipole = gt.get(1, 1, transition_energy=0, scaled=True)
      39           1 :     np.testing.assert_allclose(gt_dipole_dipole.m, gt_reference, rtol=1e-6, atol=1e-16)
      40             : 
      41             : 
      42           1 : @pytest.mark.parametrize("distance_vector_mum", DISTANCE_VECTOR_MUM_LIST)
      43           1 : def test_static_green_tensor_pair_potential(pi_module: PairinteractionModule, distance_vector_mum: list[float]) -> None:
      44           1 :     ket = pi_module.KetAtom("Rb", n=60, l=0, m=0.5)
      45           1 :     basis = pi_module.BasisAtom("Rb", n=(ket.n - 2, ket.n + 2), l=(0, 2))
      46           1 :     system = pi_module.SystemAtom(basis)
      47           1 :     system.set_magnetic_field([0, 0, 1], "gauss")
      48           1 :     system.set_electric_field([0, 0, 1], "V/cm")
      49           1 :     system.diagonalize()
      50             : 
      51           1 :     pair_energy_ghz = 2 * system.get_corresponding_energy(ket, unit="GHz")
      52           1 :     energy_range_ghz = (pair_energy_ghz - 3, pair_energy_ghz + 3)
      53           1 :     basis_pair = pi_module.BasisPair([system, system], energy=energy_range_ghz, energy_unit="GHz")
      54             : 
      55           1 :     system_pair_vacuum = pi_module.SystemPair(basis_pair)
      56           1 :     system_pair_vacuum.set_distance_vector(distance_vector_mum, unit="micrometer")
      57           1 :     system_pair_vacuum.set_interaction_order(3)
      58             : 
      59           1 :     gt = GreenTensorFreeSpace([0, 0, 0], distance_vector_mum, unit="micrometer", interaction_order=3, static_limit=True)
      60           1 :     gt.set_relative_permittivity(1.0)
      61           1 :     system_pair_free_space = pi_module.SystemPair(basis_pair).set_green_tensor(gt)
      62             : 
      63           1 :     pi_module.diagonalize([system_pair_free_space, system_pair_vacuum], sort_by_energy=True)
      64           1 :     np.testing.assert_allclose(
      65             :         system_pair_vacuum.get_eigenenergies("GHz") - pair_energy_ghz,
      66             :         system_pair_free_space.get_eigenenergies("GHz") - pair_energy_ghz,
      67             :     )
      68             : 
      69             : 
      70           1 : @pytest.mark.parametrize("distance_vector_mum", DISTANCE_VECTOR_MUM_LIST)
      71           1 : def test_vacuum_green_tensor(pi_module: PairinteractionModule, distance_vector_mum: list[float]) -> None:
      72           1 :     ket1 = pi_module.KetAtom("Rb", n=60, l=0, j=0.5, m=0.5)
      73           1 :     ket2 = pi_module.KetAtom("Rb", n=60, l=1, j=0.5, m=0.5)
      74             : 
      75           1 :     basis = pi_module.BasisAtom("Rb", n=(0, 0), additional_kets=[ket1, ket2])
      76           1 :     system = pi_module.SystemAtom(basis)
      77           1 :     pair_energy = ket1.get_energy("GHz") + ket2.get_energy("GHz")
      78           1 :     basis_pair = pi_module.BasisPair((system, system), energy=(pair_energy - 0.1, pair_energy + 0.1), energy_unit="GHz")
      79             : 
      80           1 :     dd = ket1.get_matrix_element(ket2, "electric_dipole", q=0)
      81           1 :     gt_reference = reference_green_tensor_vacuum(distance_vector_mum)
      82           1 :     reference = dd * gt_reference[2, 2] * dd
      83             : 
      84             :     # test internal vacuum green tensor
      85           1 :     system_pair = pi_module.SystemPair(basis_pair)
      86           1 :     system_pair.set_distance_vector(distance_vector_mum, "micrometer")
      87           1 :     hamiltonian = system_pair.get_hamiltonian("hartree").toarray()
      88           1 :     np.testing.assert_allclose(hamiltonian[1, 0], reference)
      89             : 
      90             :     # test custom free space vacuum green tensor
      91           1 :     system_pair = pi_module.SystemPair(basis_pair)
      92           1 :     gt = GreenTensorFreeSpace([0, 0, 0], distance_vector_mum, unit="micrometer", static_limit=True)
      93           1 :     system_pair.set_green_tensor(gt)
      94           1 :     hamiltonian = system_pair.get_hamiltonian("hartree").toarray()
      95           1 :     np.testing.assert_allclose(hamiltonian[1, 0], reference)
      96             : 
      97             : 
      98           1 : def reference_green_tensor_vacuum(distance_vector_mum: list[float]) -> NDArray:
      99           1 :     distance_mum = np.linalg.norm(distance_vector_mum)
     100           1 :     distance_au = ureg.Quantity(distance_mum, "micrometer").to_base_units().m
     101           1 :     gt: NDArray = (
     102             :         np.eye(3) - 3 * np.outer(distance_vector_mum, distance_vector_mum) / distance_mum**2
     103             :     ) / distance_au**3
     104           1 :     return gt

Generated by: LCOV version 1.16