Source code for quantarhei.qm.liouvillespace.systembathinteraction

# -*- coding: utf-8 -*-
"""
    Quantarhei package (http://www.github.com/quantarhei)

    systembathinteraction module

"""
import numpy

from ...core.saveable import Saveable
from ...qm.corfunctions.cfmatrix import CorrelationFunctionMatrix
from ... import REAL

[docs]class SystemBathInteraction(Saveable): """Describes interaction of an open quantum system with its environment Stores the system--bath interaction operator in form of a set of operators on the Hilbert space of the system and correlation functions of the operator on the bath Hilbert space. Parameters ---------- sys_operators : list List of the system part of the system-bath interaction Hamiltonian components bath_correlation_matrix: CorrelationFunctionMatrix Object of the CorrelationFunctionMatrix type holding all correlation functions needed for the description of system bath interaction rates : list/tuple List or tuple of rates. The total number of rates has to be the same as the number of operators in the ``sys_operator`` list drates : array An array of dephasing rates. The dimension of the array must correspond to the dimension of the treated system. dtype : str Type of the dehasing defined in `drates`. The types are "Lorentzian" which is default, and correponds to a dephasing rate equation with the term -\gamma\rho_{ab} on the right hand side. The dephasing is exponential. The type "Gaussian" results in a Gaussian dephasing and corresponds to the term -\gamma t \rho_{ab} on the right hand side of the rate equation. osites : list, array List or array of site indices on which the oscillators reside. The indices can repeat, indicating several modes on a single site. orates : array Oscillator decay rates. This rates corresponds to the dephasing rate of the oscillations in a harmonic oscillator system : {Molecule, Aggregate} Molecule or Aggregate object in which the system--bath interaction is specified """ def __init__(self, sys_operators=None, bath_correlation_matrix=None, rates=None, drates=None, dtype="Lorentzian", osites=None, orates=None, system=None): # information about aggregate is needed when dealing with # multiple excitons self.aggregate = None self.molecule = None self.system = None self.rates = None self.KK = None self.CC = None self.TimeAxis = None self.drates = None self.N = 0 self.osites = None self.orates = None self.sbitype = "Linear_Coupling" # version with bath correlation functions if ((sys_operators is not None) and (bath_correlation_matrix is not None)): self.sbitype = "Linear_Coupling" # Find the length of the list of operators if isinstance(sys_operators,list): self.N = len(sys_operators) else: raise Exception("sys_operators argument has to a list") # Second argument has to be a CorrelationFunctionMatrix if not isinstance(bath_correlation_matrix, CorrelationFunctionMatrix): raise Exception("ba_correlation_function argument has to a"+ " CorrelationFunctionMatrix") # Check that sys_operators and bath_correlation matrix has # a compatible number of components if bath_correlation_matrix.nob != self.N: raise Exception("Incompatile number of bath compoments: " + ("Correlation function matrix - %i vs. operators %i" % (bath_correlation_matrix.nob,self.N))) self.TimeAxis = bath_correlation_matrix.timeAxis self.set_system(system) if self.N > 0: self._set_operators(sys_operators) self.CC = bath_correlation_matrix # version with system-bath operators and rates elif ((sys_operators is not None) and (rates is not None)): self.sbitype = "Lindblad_Form" # Find the length of the list of operators if isinstance(sys_operators, list): self.N = len(sys_operators) else: raise Exception("First argument has to a list") self.set_system(system) if self.N > 0: self._set_operators(sys_operators) self.CC = None #bath_correlation_matrix if len(rates) != self.N: raise Exception("Wrong number of rates specified") self.rates = rates elif ((sys_operators is None) and (drates is not None)): self.sbitype = "Pure_Dephasing" if len(drates.shape) != 2: raise Exception("Pure dephasing rates must" +" be defined by a matrix") if drates.shape[0] != drates.shape[1]: raise Exception("Pure dephasing rates must" +" be defined by a square matrix") self.N = drates.shape[0] self.set_system(system) self.CC = None elif ((sys_operators is None) and (orates is not None)): self.sbitype = "Vibrational_Lindblad_Form" if len(orates) != len(osites): raise Exception("`orates` and `osites` arguments must"+ " have the same lengths") self.set_system(system) self.CC = None self.orates = orates self.osites = osites
[docs] def set_system(self, system): """Sets the system attribute """ from ...builders.aggregates import Aggregate from ...builders.molecules import Molecule if system is not None: if isinstance(system, Aggregate): self.aggregate = system self.molecule = None self.system = self.aggregate elif isinstance(system, Molecule): self.aggregate = None self.molecule = system self.system = self.molecule else: raise Exception("Unknown system type")
def _set_operators(self, sys_operators): """Sets the system part of the interaction """ # First of the operators KK = sys_operators[0] # Get its dimension dim = KK.data.shape[0] self.KK = numpy.zeros((self.N, dim, dim), dtype=REAL) self.KK[0,:,:] = numpy.real(KK.data) # Save other operators and check their dimensions for ii in range(1,self.N): KK = sys_operators[ii] if True: #isinstance(KK,Operator): if dim == KK.data.shape[0]: self.KK[ii,:,:] = KK.data else: raise Exception("Operators in the list are" + " not of the same dimension") else: raise Exception("sys_operators tuple (the first argument)" + " has to contain cu.oqs.hilbertspace.Operator")
[docs] def get_coft(self, n, m): """Returns bath correlation function corresponding to sites n and m """ if self.sbitype != "Linear_Coupling": raise Exception("Correlation functions only defined for "+ "linear microscopic system-bath coupling") if self.system is None: return self.CC.get_coft(n,m) else: #FIXME: Molecule needs this method bn = self.system.which_band[n] bm = self.system.which_band[m] if ((bn == 0) and (bm == 0)): #print(bn,"::",n,m) return self.CC._cofts[0,:] elif ((bn == 1) and (bm == 1)): #print(bn,"::",n-1,m-1) return self.CC.get_coft(n-1,m-1) else: return self.CC._cofts[0,:]
[docs] def get_coft_elsig(self, n_sig, m_sig): """Returns bath correlation based on electronic signatures """ if self.sbitype != "Linear_Coupling": raise Exception("Correlation functions only defined for "+ "linear microscopic system-bath coupling") nb = numpy.sum(n_sig) mb = numpy.sum(m_sig) indices = [] if mb == nb: ni = 0 for na in n_sig: mi = 0 for ma in m_sig: if ((na == 1) and (ma == 1)): indices.append([ni,mi]) mi += 1 ni += 1 ret = numpy.zeros((self.TimeAxis.length),dtype=numpy.complex128) for ind in indices: #print(nb,":",ind[0],ind[1]) ret += self.get_coft(ind[0],ind[1]) return ret else: return self.CC._cofts[0,:]
[docs] def has_temperature(self): """Checkst if the Aggregate has a defined temperature """ if (self.sbitype == "Lindblad_Form" or self.sbitype == "Vibrational_Lindblad_Form"): return False else: try: T = self.get_temperature() if T >= 0.0: return True except: return False
[docs] def get_temperature(self): """Returns temperature associated with the bath """ return self.CC.get_temperature()
[docs] def get_reorganization_energy(self, i, j=None): """Returns reorganization energy associated with a given site If one index `i` is specified, the function returns reorganization energy associated with i-th site. If two indices are specified, the function returns crosscorrelation function (when i not equal j) or a correlation function of the site (when i = j) """ if (self.sbitype == "Lindblad_Form" or self.sbitype == "Vibrational_Lindblad_Form"): return None else: if j is None: j = i return self.CC.get_reorganization_energy(i,j)
def get_correlation_time(self, i, j=None): if (self.sbitype == "Lindblad_Form" or self.sbitype == "Vibrational_Lindblad_Form"): return None else: if j is None: j = i return self.CC.get_correlation_time(i,j)
[docs] def get_sbitype(self): """Returns the type of SystemBathInteraction Options are `Lindblad_Form`, `Vibrational_Lindblad_Form` and `Linear_Coupling` """ return self.sbitype