Source code for quantarhei.qm.liouvillespace.foerstertensor

from __future__ import annotations

import numpy

from ... import COMPLEX
from ...core.managers import energy_units
from ...exceptions import QuantarheiError

# import scipy.interpolate as interp
from ..hilbertspace.hamiltonian import Hamiltonian
from ..liouvillespace.systembathinteraction import SystemBathInteraction
from .rates.foersterrates import FoersterRateMatrix
from .relaxationtensor import RelaxationTensor


[docs] class FoersterRelaxationTensor(RelaxationTensor): """Weak resonance coupling relaxation tensor by Foerster theory""" dim: int data: numpy.ndarray _has_cutoff_time: bool cutoff_time: float | None _is_initialized: bool def __init__( self, ham: Hamiltonian, sbi: SystemBathInteraction, initialize: bool = True, cutoff_time: float | None = None, pure_dephasing: bool = False, ) -> None: self._initialize_basis() if not isinstance(ham, Hamiltonian): raise QuantarheiError("First argument must be a Hamiltonian") if not isinstance(sbi, SystemBathInteraction): raise QuantarheiError( "Second argument must be of type SystemBathInteraction" ) self._is_initialized = False self._has_cutoff_time = False self.as_operators = False self.pure_dephasing = pure_dephasing self.has_Iterm = False if cutoff_time is not None: self.cutoff_time = cutoff_time self._has_cutoff_time = True self.Hamiltonian = ham self.dim = ham.dim self.SystemBathInteraction: SystemBathInteraction = sbi self.TimeAxis = sbi.TimeAxis if initialize: self.initialize() self._data_initialized = True self._is_initialized = True else: self._data_initialized = False
[docs] def initialize(self) -> None: # # Tensor data # Na = self.dim self.data = numpy.zeros((Na, Na, Na, Na), dtype=COMPLEX) with energy_units("int"): HH = self.Hamiltonian sbi = self.SystemBathInteraction if self._has_cutoff_time: cft = self.cutoff_time else: cft = None frm = FoersterRateMatrix(HH, sbi, initialize=True, cutoff_time=cft) # # Transfer rates # for aa in range(self.dim): for bb in range(self.dim): if aa != bb: self.data[aa, aa, bb, bb] = frm.data[aa, bb] # # calculate dephasing rates and depopulation rates # self.updateStructure() if self.pure_dephasing: # additional pure dephasing self.add_dephasing()
[docs] def add_dephasing(self) -> None: # line shape function derivatives sbi = self.SystemBathInteraction Na = self.dim Nt = sbi.TimeAxis.length ht = numpy.zeros((Na, Nt), dtype=numpy.complex64) sbi.CC.create_one_integral() for ii in range(1, Na): ht[ii, :] = sbi.CC.get_hoft(ii - 1, ii - 1) for aa in range(self.dim): for bb in range(self.dim): if aa != bb: self.data[aa, bb, aa, bb] -= ht[aa, Nt - 1] + ht[bb, Nt - 1]