예제 #1
0
    def setUp(self,verbose=False):
        
        self.verbose = verbose
        
        #
        # PURE ELECTRONIC AGGREGATE
        #
    
        m1 = Molecule([0.0, 1.0])
        m2 = Molecule([0.0, 1.0])
        
        agg = Aggregate(molecules=[m1, m2])
        
        agg.set_resonance_coupling(0,1, 0.1)
        
        agg.build()
        
        self.ham = agg.get_Hamiltonian()
                
        KK12 = ProjectionOperator(1, 2, dim=self.ham.dim)
        KK21 = ProjectionOperator(2, 1, dim=self.ham.dim)
        
        self.rates = (1.0/100.0, 1.0/200.0)
        
        self.sbi = SystemBathInteraction([KK12,KK21],
                                          rates=self.rates)
        self.sbi.set_system(agg)

        #
        #  VIBRONIC AGGREGATE
        #
        
        vm1 = Molecule([0.0, 1.0])
        vm2 = Molecule([0.0, 1.0])
        mod1 = Mode(0.01)
        mod2 = Mode(0.01)
        vm1.add_Mode(mod1)
        vm2.add_Mode(mod2)
                
        mod1.set_nmax(0, 3)
        mod1.set_nmax(1, 3)
        
        mod2.set_nmax(0, 3)
        mod2.set_nmax(1, 3)
        
        vagg = Aggregate(molecules=[vm1, vm2])
        vagg.set_resonance_coupling(0, 1, 0.1)
        
        vagg.build()
        
        self.vham = vagg.get_Hamiltonian()
        
        self.vsbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.vsbi.set_system(vagg)       
예제 #2
0
    def setUp(self, verbose=False):

        self.verbose = verbose

        #
        # PURE ELECTRONIC AGGREGATE
        #

        m1 = Molecule([0.0, 1.0])
        m2 = Molecule([0.0, 1.0])

        agg = Aggregate(molecules=[m1, m2])

        agg.set_resonance_coupling(0, 1, 0.1)

        agg.build()

        self.ham = agg.get_Hamiltonian()

        KK12 = ProjectionOperator(1, 2, dim=self.ham.dim)
        KK21 = ProjectionOperator(2, 1, dim=self.ham.dim)

        self.rates = (1.0 / 100.0, 1.0 / 200.0)

        self.sbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.sbi.set_system(agg)

        #
        #  VIBRONIC AGGREGATE
        #

        vm1 = Molecule([0.0, 1.0])
        vm2 = Molecule([0.0, 1.0])
        mod1 = Mode(0.01)
        mod2 = Mode(0.01)
        vm1.add_Mode(mod1)
        vm2.add_Mode(mod2)

        mod1.set_nmax(0, 3)
        mod1.set_nmax(1, 3)

        mod2.set_nmax(0, 3)
        mod2.set_nmax(1, 3)

        vagg = Aggregate(molecules=[vm1, vm2])
        vagg.set_resonance_coupling(0, 1, 0.1)

        vagg.build()

        self.vham = vagg.get_Hamiltonian()

        self.vsbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.vsbi.set_system(vagg)
예제 #3
0
    def setUp(self, verbose=False):

        self.verbose = verbose

        time = TimeAxis(0.0, 1000, 1.0)
        with energy_units("1/cm"):
            params = {
                "ftype": "OverdampedBrownian",
                "reorg": 30.0,
                "T": 300.0,
                "cortime": 100.0
            }

            cf1 = CorrelationFunction(time, params)
            cf2 = CorrelationFunction(time, params)
            sd = SpectralDensity(time, params)

        cm1 = CorrelationFunctionMatrix(time, 2, 1)
        cm1.set_correlation_function(cf1, [(0, 0), (1, 1)])
        cm2 = CorrelationFunctionMatrix(time, 2, 1)
        cm2.set_correlation_function(cf2, [(0, 0), (1, 1)])

        K11 = numpy.array([[1.0, 0.0], [0.0, 0.0]], dtype=numpy.float)
        K21 = numpy.array([[1.0, 0.0], [0.0, 0.0]], dtype=numpy.float)
        K12 = K11.copy()
        K22 = K21.copy()

        KK11 = Operator(data=K11)
        KK21 = Operator(data=K21)
        KK12 = Operator(data=K12)
        KK22 = Operator(data=K22)

        self.sbi1 = SystemBathInteraction([KK11, KK21], cm1)
        self.sbi2 = SystemBathInteraction([KK12, KK22], cm2)

        with energy_units("1/cm"):
            h1 = [[0.0, 100.0], [100.0, 0.0]]
            h2 = [[0.0, 100.0], [100.0, 0.0]]
            self.H1 = Hamiltonian(data=h1)
            self.H2 = Hamiltonian(data=h2)

        #sd.convert_2_spectral_density()
        with eigenbasis_of(self.H1):
            de = self.H1.data[1, 1] - self.H1.data[0, 0]
        self.c_omega_p = sd.at(de, approx="spline")  #interp_data(de)
        self.c_omega_m = sd.at(-de, approx="spline")  #interp_data(-de)
예제 #4
0
    def setUp(self, verbose=False):

        self.verbose = verbose

        K12 = numpy.array([[0.0, 1.0], [0.0, 0.0]], dtype=numpy.float)
        K21 = numpy.array([[0.0, 0.0], [1.0, 0.0]], dtype=numpy.float)

        KK12 = Operator(data=K12)
        KK21 = Operator(data=K21)

        self.KK12 = KK12
        self.KK21 = KK21
        self.rates = (1.0 / 100.0, 1.0 / 200.0)

        self.sbi1 = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.sbi2 = SystemBathInteraction([KK12, KK21], rates=self.rates)

        with energy_units("1/cm"):
            h1 = [[100.0, 0.0], [0.0, 0.0]]
            h2 = [[100.0, 0.0], [0.0, 0.0]]
            self.H1 = Hamiltonian(data=h1)
            self.H2 = Hamiltonian(data=h2)
예제 #5
0
#
# Operator describing relaxation
#
from quantarhei.qm import Operator

HH = agg.get_Hamiltonian()
K = Operator(dim=HH.dim, real=True)
K.data[1, 2] = 1.0

#
# System bath interaction with prescribed rate
#
from quantarhei.qm import SystemBathInteraction

sbi = SystemBathInteraction(sys_operators=[K], rates=(1.0 / 100, ))
agg.set_SystemBathInteraction(sbi)

#
# Corresponding Lindblad form
#
from quantarhei.qm import LindbladForm

LF = LindbladForm(HH, sbi, as_operators=False)

print(LF.data[1, 1, 2, 2])
print(LF.data[1, 2, 1, 2])

#
# We can get it also from the aggregate
#
예제 #6
0
    def setUp(self, verbose=False):

        self.verbose = verbose

        #
        # Lindblad projection operators
        #
        K12 = numpy.array([[0.0, 1.0], [0.0, 0.0]], dtype=numpy.float)
        K21 = numpy.array([[0.0, 0.0], [1.0, 0.0]], dtype=numpy.float)

        KK12 = Operator(data=K12)
        KK21 = Operator(data=K21)

        self.KK12 = KK12
        self.KK21 = KK21

        #
        # Linbdlad rates
        #
        self.rates = (1.0 / 100.0, 1.0 / 200.0)

        #
        # System-bath interaction using operators and rates in site basis
        #
        self.sbi1 = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.sbi2 = SystemBathInteraction([KK12, KK21], rates=self.rates)

        #
        # Test Hamiltonians
        #
        with energy_units("1/cm"):
            h1 = [[100.0, 0.0], [0.0, 0.0]]
            h2 = [[100.0, 0.0], [0.0, 0.0]]
            self.H1 = Hamiltonian(data=h1)
            self.H2 = Hamiltonian(data=h2)

            h3 = [[100.0, 20.0], [20.0, 0.0]]
            self.H3 = Hamiltonian(data=h3)

            # less trivial Hamiltonian
            h4 = [[100.0, 200.0, 30.0], [200.0, 50.0, -100.0],
                  [30.0, -100.0, 0.0]]
            self.H4 = Hamiltonian(data=h4)

            h4s = [[100.0, 0.0, 0.0], [0.0, 50.0, 0.0], [0.0, 0.0, 0.0]]

            self.H4s = Hamiltonian(data=h4s)

        #
        # Projection operators in eigenstate basis
        #
        with eigenbasis_of(self.H3):
            K_12 = ProjectionOperator(0, 1, dim=2)
            K_21 = ProjectionOperator(1, 0, dim=2)
            self.K_12 = K_12
            self.K_21 = K_21

        with eigenbasis_of(self.H4):
            Ke_12 = ProjectionOperator(0, 1, dim=3)
            Ke_21 = ProjectionOperator(1, 0, dim=3)
            Ke_23 = ProjectionOperator(1, 2, dim=3)
            Ke_32 = ProjectionOperator(2, 1, dim=3)

        Ks_12 = ProjectionOperator(0, 1, dim=3)
        Ks_21 = ProjectionOperator(1, 0, dim=3)
        Ks_23 = ProjectionOperator(1, 2, dim=3)
        Ks_32 = ProjectionOperator(2, 1, dim=3)

        self.rates4 = [1.0 / 100, 1.0 / 200, 1.0 / 150, 1.0 / 300]

        #
        # System-bath operators defined in exciton basis
        #
        self.sbi3 = SystemBathInteraction([K_12, K_21], rates=self.rates)

        self.sbi4e = SystemBathInteraction([Ke_12, Ke_21, Ke_23, Ke_32],
                                           rates=self.rates4)
        self.sbi4s = SystemBathInteraction([Ks_12, Ks_21, Ks_23, Ks_32],
                                           rates=self.rates4)
예제 #7
0
class TestElectronicLindblad(unittest.TestCase):
    """Tests for the ElectronicLindbladForm class
    
    
    """
    def setUp(self, verbose=False):

        self.verbose = verbose

        #
        # PURE ELECTRONIC AGGREGATE
        #

        m1 = Molecule([0.0, 1.0])
        m2 = Molecule([0.0, 1.0])

        agg = Aggregate(molecules=[m1, m2])

        agg.set_resonance_coupling(0, 1, 0.1)

        agg.build()

        self.ham = agg.get_Hamiltonian()

        KK12 = ProjectionOperator(1, 2, dim=self.ham.dim)
        KK21 = ProjectionOperator(2, 1, dim=self.ham.dim)

        self.rates = (1.0 / 100.0, 1.0 / 200.0)

        self.sbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.sbi.set_system(agg)

        #
        #  VIBRONIC AGGREGATE
        #

        vm1 = Molecule([0.0, 1.0])
        vm2 = Molecule([0.0, 1.0])
        mod1 = Mode(0.01)
        mod2 = Mode(0.01)
        vm1.add_Mode(mod1)
        vm2.add_Mode(mod2)

        mod1.set_nmax(0, 3)
        mod1.set_nmax(1, 3)

        mod2.set_nmax(0, 3)
        mod2.set_nmax(1, 3)

        vagg = Aggregate(molecules=[vm1, vm2])
        vagg.set_resonance_coupling(0, 1, 0.1)

        vagg.build()

        self.vham = vagg.get_Hamiltonian()

        self.vsbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.vsbi.set_system(vagg)

    def test_comparison_of_rates_in_electronic(self):
        """Testing that ElectronicLindblad and rate matrix are compatible
        
        This is for the case that everything is electronic
        
        
        """

        dim = self.ham.dim
        KT = numpy.zeros((dim, dim), dtype=numpy.float64)
        KM = numpy.zeros((dim, dim), dtype=numpy.float64)

        LT = ElectronicLindbladForm(self.ham, self.sbi, as_operators=False)

        for n in range(dim):
            for m in range(dim):
                KT[n, m] = numpy.real(LT.data[n, n, m, m])

        KM = numpy.zeros((dim, dim))
        KM[1, 1] = -self.rates[1]
        KM[2, 2] = -self.rates[0]
        KM[1, 2] = self.rates[0]
        KM[2, 1] = self.rates[1]

        #print("KT = ", KT)
        #print("KM = ", KM)
        #print("LT = ", LT.data)

        numpy.testing.assert_allclose(KT, KM, rtol=1.0e-2)

    def test_construction_electronic_lindblad(self):
        """Testing construction of electronic Lindblad form for vibronic system
         
        """

        LT = ElectronicLindbladForm(self.vham, self.vsbi, as_operators=False)

        dim = self.vham.dim
        zer = numpy.zeros((dim, dim, dim, dim), dtype=numpy.float64)
        numpy.testing.assert_array_equal(LT._data - LT._data, zer)

    def test_comparison_with_and_without_vib(self):
        """Testing ElectronicLindbladForm in propagation
        
        """

        # Lindblad forms
        LT = ElectronicLindbladForm(self.ham, self.sbi, as_operators=False)
        vLT = ElectronicLindbladForm(self.vham, self.vsbi, as_operators=False)

        # Propagators
        time = TimeAxis(0.0, 1000, 1.0)
        el_prop = ReducedDensityMatrixPropagator(time, self.ham, LT)
        vib_prop = ReducedDensityMatrixPropagator(time, self.vham, vLT)

        # electronic initial condition
        rho0 = ReducedDensityMatrix(dim=self.ham.dim)
        rho0.data[2, 2] = 1.0

        # vibronic intial condition
        vrho0 = ReducedDensityMatrix(dim=self.vham.dim)
        agg = self.vsbi.system
        Nin = agg.vibindices[2][0]
        vrho0.data[Nin, Nin] = 1.0

        # propagations
        rhot = el_prop.propagate(rho0)
        vrhot = vib_prop.propagate(vrho0)

        # averaging over vibrational level at t=0
        Nel = agg.Nel

        aver_vrhot0 = agg.trace_over_vibrations(vrho0)

        # Test
        numpy.testing.assert_allclose(rhot._data[0, :, :], rho0._data)
        numpy.testing.assert_allclose(rhot._data[0, :, :], aver_vrhot0._data)

        aver_vrhot10 = agg.trace_over_vibrations(vrhot, 10)
        numpy.testing.assert_allclose(rhot._data[10, :, :], aver_vrhot10._data)

        aver_vrhot800 = agg.trace_over_vibrations(vrhot, 800)
        numpy.testing.assert_allclose(rhot._data[800, :, :],
                                      aver_vrhot800._data)
예제 #8
0
#
# Operator describing relaxation
#
from quantarhei.qm import Operator

HH = agg.get_Hamiltonian()
K = Operator(dim=HH.dim,real=True)
K.data[1,2] = 1.0

#
# System bath interaction with prescribed rate
#
from quantarhei.qm import SystemBathInteraction

sbi = SystemBathInteraction(sys_operators=[K], rates=(1.0/100,))
agg.set_SystemBathInteraction(sbi)

#
# Corresponding Lindblad form
#
from quantarhei.qm import LindbladForm

LF = LindbladForm(HH, sbi, as_operators=False)

print(LF.data[1,1,2,2])
print(LF.data[1,2,1,2])

#
# We can get it also from the aggregate
#
    def test_LindbladWithVibrations_dynamics_comp(self):
        """Compares Lindblad dynamics of a system with vibrations calculated from propagator and superoperator
        
        
        
        """
        # Aggregate
        import quantarhei as qr
        
        time = qr.TimeAxis(0.0, 1000, 1.0)
        
        # create a model
        with qr.energy_units("1/cm"):
            
            me1 = qr.Molecule([0.0, 12100.0])
            me2 = qr.Molecule([0.0, 12000.0])
            me3 = qr.Molecule([0.0, 12900.0])
            
            agg_el = qr.Aggregate([me1, me2, me3])
            
            agg_el.set_resonance_coupling(0, 1, qr.convert(150, "1/cm", to="int"))
            agg_el.set_resonance_coupling(1, 2, qr.convert(50, "1/cm", to="int"))
 
            m1 = qr.Molecule([0.0, 12100.0])
            m2 = qr.Molecule([0.0, 12000.0])
            m3 = qr.Molecule([0.0, 12900.0])
           
            mod1 = qr.Mode(frequency=qr.convert(100, "1/cm", "int"))
            m1.add_Mode(mod1)
            mod1.set_HR(1, 0.01)
            
            agg = qr.Aggregate([m1, m2, m3])
            
            agg.set_resonance_coupling(0, 1, qr.convert(150, "1/cm", to="int"))
            agg.set_resonance_coupling(1, 2, qr.convert(50, "1/cm", to="int"))
            
        
        agg_el.build()
        agg.build()
        
        hame = agg_el.get_Hamiltonian()
        ham = agg.get_Hamiltonian()

        # calculate relaxation tensor

        with qr.eigenbasis_of(hame):
        
            #
            # Operator describing relaxation
            #

            K = qr.qm.ProjectionOperator(1, 2, dim=hame.dim)      

            #
            # System bath interaction with prescribed rate
            #
            from quantarhei.qm import SystemBathInteraction

            sbi = SystemBathInteraction(sys_operators=[K], rates=(1.0/100.0,))
            sbi.set_system(agg) #agg.set_SystemBathInteraction(sbi) 
            
            
        with qr.eigenbasis_of(ham):

            #
            # Corresponding Lindblad form
            #
            from quantarhei.qm import ElectronicLindbladForm

            LF = ElectronicLindbladForm(ham, sbi, as_operators=True)       
            
            
            #
            # Evolution of reduced density matrix
            #
            prop = qr.ReducedDensityMatrixPropagator(time, ham, LF)        
            
            
            
            #
            # Evolution by superoperator
            #
            
            eSO = qr.qm.EvolutionSuperOperator(time, ham, LF)
            eSO.set_dense_dt(5)
            eSO.calculate()
            
            # compare the two propagations
            pairs = [(5,4), (5,5), (6,5), (7,5)]
            for p in pairs:
                
            
                rho_i1 = qr.ReducedDensityMatrix(dim=ham.dim)
                rho_i1.data[p[0],p[1]] = 1.0
            
                rho_t1 = prop.propagate(rho_i1)

            
                exp_rho_t2 = eSO.data[:,:,:,p[0],p[1]]


                #import matplotlib.pyplot as plt
        
                #plt.plot(rho_t1.TimeAxis.data, numpy.real(rho_t1.data[:,p[0],p[1]]), "-r")
                #plt.plot(rho_t1.TimeAxis.data, numpy.real(exp_rho_t2[:,p[0],p[1]]), "--g")
                #plt.show()
                
                #for kk in range(rho_t1.TimeAxis.length):
                #    print(kk, numpy.real(rho_t1.data[kk,p[0],p[1]]),numpy.real(exp_rho_t2[kk,p[0],p[1]]))

                #numpy.testing.assert_allclose(RRT.data, rtd)
                numpy.testing.assert_allclose(numpy.real(rho_t1.data[:,:,:]),
                                          numpy.real(exp_rho_t2[:,:,:]), 
                                          rtol=5.0e-2,
                                          atol=1.0e-3)
예제 #10
0
m3v.add_Mode(mod3)
mod3.set_nmax(0, Nvib)
mod3.set_nmax(1, Nvib)
mod3.set_HR(1, 0.3)

vagg = Aggregate(molecules=[m1v, m2v, m3v])
vagg.build()

from quantarhei.qm import ProjectionOperator

K12 = ProjectionOperator(1, 2, dim=4)
K23 = ProjectionOperator(2, 3, dim=4)
ops = [K12, K23]
rates = [1.0/100.0, 1.0/150.0]

vsbi = SystemBathInteraction(sys_operators=ops, rates=rates)
vsbi.set_system(vagg)

from quantarhei.qm import ElectronicLindbladForm

ham = vagg.get_Hamiltonian()
print("Hamiltonian dimension: ", ham.dim)
print("Constructing electronic Lindblad form")
eLF = ElectronicLindbladForm(ham, vsbi, as_operators=True)
print("...done")

time = TimeAxis(0.0, 1000, 1.0)

from quantarhei.qm import ReducedDensityMatrixPropagator
vibprop = ReducedDensityMatrixPropagator(time, ham, eLF)
    def test_Lindblad_dynamics_comp(self):
        """Compares Lindblad dynamics calculated from propagator and superoperator
        
        
        
        """
        # Aggregate
        import quantarhei as qr
        import quantarhei.models.modelgenerator as mgen

        time = qr.TimeAxis(0.0, 1000, 1.0)

        # create a model
        mg = mgen.ModelGenerator()

        agg = mg.get_Aggregate(name="trimer-1")

        agg.build()

        ham = agg.get_Hamiltonian()

        # calculate relaxation tensor

        with qr.eigenbasis_of(ham):

            #
            # Operator describing relaxation
            #
            from quantarhei.qm import Operator

            K = Operator(dim=ham.dim, real=True)
            K.data[1, 2] = 1.0

            #
            # System bath interaction with prescribed rate
            #
            from quantarhei.qm import SystemBathInteraction

            sbi = SystemBathInteraction(sys_operators=[K],
                                        rates=(1.0 / 100.0, ))
            agg.set_SystemBathInteraction(sbi)

            #
            # Corresponding Lindblad form
            #
            from quantarhei.qm import LindbladForm

            LF = LindbladForm(ham, sbi, as_operators=False)

            #
            # Evolution of reduced density matrix
            #
            prop = qr.ReducedDensityMatrixPropagator(time, ham, LF)

            #
            # Evolution by superoperator
            #

            eSO = qr.qm.EvolutionSuperOperator(time, ham, LF)
            eSO.set_dense_dt(5)
            eSO.calculate()

            # compare the two propagations
            pairs = [(1, 3), (3, 2), (3, 3)]
            for p in pairs:

                rho_i1 = qr.ReducedDensityMatrix(dim=ham.dim)
                rho_i1.data[p[0], p[1]] = 1.0

                rho_t1 = prop.propagate(rho_i1)

                exp_rho_t2 = eSO.data[:, :, :, p[0], p[1]]

                #import matplotlib.pyplot as plt

                #plt.plot(rho_t1.TimeAxis.data, numpy.real(rho_t1.data[:,p[0],p[1]]))
                #plt.plot(rho_t1.TimeAxis.data, numpy.real(exp_rho_t2[:,p[0],p[1]]))
                #plt.show()

                #numpy.testing.assert_allclose(RRT.data, rtd)
                numpy.testing.assert_allclose(numpy.real(rho_t1.data[:, :, :]),
                                              numpy.real(exp_rho_t2[:, :, :]),
                                              rtol=1.0e-7,
                                              atol=1.0e-6)
    def test_LindbladWithVibrations_dynamics_comp(self):
        """Compares Lindblad dynamics of a system with vibrations calculated from propagator and superoperator
        
        
        
        """
        # Aggregate
        import quantarhei as qr

        time = qr.TimeAxis(0.0, 1000, 1.0)

        # create a model
        with qr.energy_units("1/cm"):

            me1 = qr.Molecule([0.0, 12100.0])
            me2 = qr.Molecule([0.0, 12000.0])
            me3 = qr.Molecule([0.0, 12900.0])

            agg_el = qr.Aggregate([me1, me2, me3])

            agg_el.set_resonance_coupling(0, 1,
                                          qr.convert(150, "1/cm", to="int"))
            agg_el.set_resonance_coupling(1, 2, qr.convert(50,
                                                           "1/cm",
                                                           to="int"))

            m1 = qr.Molecule([0.0, 12100.0])
            m2 = qr.Molecule([0.0, 12000.0])
            m3 = qr.Molecule([0.0, 12900.0])

            mod1 = qr.Mode(frequency=qr.convert(100, "1/cm", "int"))
            m1.add_Mode(mod1)
            mod1.set_HR(1, 0.01)

            agg = qr.Aggregate([m1, m2, m3])

            agg.set_resonance_coupling(0, 1, qr.convert(150, "1/cm", to="int"))
            agg.set_resonance_coupling(1, 2, qr.convert(50, "1/cm", to="int"))

        agg_el.build()
        agg.build()

        hame = agg_el.get_Hamiltonian()
        ham = agg.get_Hamiltonian()

        # calculate relaxation tensor

        with qr.eigenbasis_of(hame):

            #
            # Operator describing relaxation
            #

            K = qr.qm.ProjectionOperator(1, 2, dim=hame.dim)

            #
            # System bath interaction with prescribed rate
            #
            from quantarhei.qm import SystemBathInteraction

            sbi = SystemBathInteraction(sys_operators=[K],
                                        rates=(1.0 / 100.0, ))
            sbi.set_system(agg)  #agg.set_SystemBathInteraction(sbi)

        with qr.eigenbasis_of(ham):

            #
            # Corresponding Lindblad form
            #
            from quantarhei.qm import ElectronicLindbladForm

            LF = ElectronicLindbladForm(ham, sbi, as_operators=True)

            #
            # Evolution of reduced density matrix
            #
            prop = qr.ReducedDensityMatrixPropagator(time, ham, LF)

            #
            # Evolution by superoperator
            #

            eSO = qr.qm.EvolutionSuperOperator(time, ham, LF)
            eSO.set_dense_dt(5)
            eSO.calculate()

            # compare the two propagations
            pairs = [(5, 4), (5, 5), (6, 5), (7, 5)]
            for p in pairs:

                rho_i1 = qr.ReducedDensityMatrix(dim=ham.dim)
                rho_i1.data[p[0], p[1]] = 1.0

                rho_t1 = prop.propagate(rho_i1)

                exp_rho_t2 = eSO.data[:, :, :, p[0], p[1]]

                #import matplotlib.pyplot as plt

                #plt.plot(rho_t1.TimeAxis.data, numpy.real(rho_t1.data[:,p[0],p[1]]), "-r")
                #plt.plot(rho_t1.TimeAxis.data, numpy.real(exp_rho_t2[:,p[0],p[1]]), "--g")
                #plt.show()

                #for kk in range(rho_t1.TimeAxis.length):
                #    print(kk, numpy.real(rho_t1.data[kk,p[0],p[1]]),numpy.real(exp_rho_t2[kk,p[0],p[1]]))

                #numpy.testing.assert_allclose(RRT.data, rtd)
                numpy.testing.assert_allclose(numpy.real(rho_t1.data[:, :, :]),
                                              numpy.real(exp_rho_t2[:, :, :]),
                                              rtol=5.0e-2,
                                              atol=1.0e-3)
예제 #13
0
class TestElectronicLindblad(unittest.TestCase):
    """Tests for the ElectronicLindbladForm class
    
    
    """
    
    def setUp(self,verbose=False):
        
        self.verbose = verbose
        
        #
        # PURE ELECTRONIC AGGREGATE
        #
    
        m1 = Molecule([0.0, 1.0])
        m2 = Molecule([0.0, 1.0])
        
        agg = Aggregate(molecules=[m1, m2])
        
        agg.set_resonance_coupling(0,1, 0.1)
        
        agg.build()
        
        self.ham = agg.get_Hamiltonian()
                
        KK12 = ProjectionOperator(1, 2, dim=self.ham.dim)
        KK21 = ProjectionOperator(2, 1, dim=self.ham.dim)
        
        self.rates = (1.0/100.0, 1.0/200.0)
        
        self.sbi = SystemBathInteraction([KK12,KK21],
                                          rates=self.rates)
        self.sbi.set_system(agg)

        #
        #  VIBRONIC AGGREGATE
        #
        
        vm1 = Molecule([0.0, 1.0])
        vm2 = Molecule([0.0, 1.0])
        mod1 = Mode(0.01)
        mod2 = Mode(0.01)
        vm1.add_Mode(mod1)
        vm2.add_Mode(mod2)
                
        mod1.set_nmax(0, 3)
        mod1.set_nmax(1, 3)
        
        mod2.set_nmax(0, 3)
        mod2.set_nmax(1, 3)
        
        vagg = Aggregate(molecules=[vm1, vm2])
        vagg.set_resonance_coupling(0, 1, 0.1)
        
        vagg.build()
        
        self.vham = vagg.get_Hamiltonian()
        
        self.vsbi = SystemBathInteraction([KK12, KK21], rates=self.rates)
        self.vsbi.set_system(vagg)       
        
        
    def test_comparison_of_rates_in_electronic(self):
        """Testing that ElectronicLindblad and rate matrix are compatible
        
        This is for the case that everything is electronic
        
        
        """ 
        
        dim = self.ham.dim
        KT = numpy.zeros((dim,dim), dtype=numpy.float64)
        KM = numpy.zeros((dim,dim), dtype=numpy.float64)
        
        LT = ElectronicLindbladForm(self.ham, self.sbi, as_operators=False)
        
        for n in range(dim):
            for m in range(dim):
                KT[n,m] = numpy.real(LT.data[n,n,m,m])
                    
        KM = numpy.zeros((dim,dim))
        KM[1,1] = -self.rates[1]
        KM[2,2] = -self.rates[0]
        KM[1,2] = self.rates[0]
        KM[2,1] = self.rates[1]
                
        #print("KT = ", KT)
        #print("KM = ", KM)
        #print("LT = ", LT.data)
        
        numpy.testing.assert_allclose(KT,KM, rtol=1.0e-2)               


    def test_construction_electronic_lindblad(self):
        """Testing construction of electronic Lindblad form for vibronic system
         
        """
         
        LT = ElectronicLindbladForm(self.vham, self.vsbi, as_operators=False)
        
        dim = self.vham.dim
        zer = numpy.zeros((dim, dim, dim, dim), dtype=numpy.float64)
        numpy.testing.assert_array_equal(LT._data-LT._data, zer)


    def test_comparison_with_and_without_vib(self):
        """Testing ElectronicLindbladForm in propagation
        
        """
        
        # Lindblad forms
        LT = ElectronicLindbladForm(self.ham, self.sbi, as_operators=False)
        vLT = ElectronicLindbladForm(self.vham, self.vsbi, as_operators=False)
       
        # Propagators
        time = TimeAxis(0.0, 1000, 1.0)
        el_prop = ReducedDensityMatrixPropagator(time, self.ham, LT)
        vib_prop = ReducedDensityMatrixPropagator(time, self.vham, vLT)
        
        # electronic initial condition
        rho0 = ReducedDensityMatrix(dim=self.ham.dim)
        rho0.data[2,2] = 1.0
        
        # vibronic intial condition
        vrho0 = ReducedDensityMatrix(dim=self.vham.dim)
        agg = self.vsbi.system
        Nin = agg.vibindices[2][0]
        vrho0.data[Nin, Nin] = 1.0
        
        # propagations
        rhot = el_prop.propagate(rho0)
        vrhot = vib_prop.propagate(vrho0)
        
        # averaging over vibrational level at t=0
        Nel = agg.Nel
        
        aver_vrhot0 = agg.trace_over_vibrations(vrho0) 
                
        # Test
        numpy.testing.assert_allclose(rhot._data[0,:,:], rho0._data)
        numpy.testing.assert_allclose(rhot._data[0,:,:], aver_vrhot0._data)
        
        aver_vrhot10 = agg.trace_over_vibrations(vrhot, 10)
        numpy.testing.assert_allclose(rhot._data[10,:,:], 
                                         aver_vrhot10._data)        
     
        aver_vrhot800 = agg.trace_over_vibrations(vrhot, 800)
        numpy.testing.assert_allclose(rhot._data[800,:,:], 
                                         aver_vrhot800._data)