Source code for quantarhei.builders.aggregate_test

# -*- coding: utf-8 -*-
"""
    Class to support tests on Aggregate class

    This class provides an easy access to a prefilled, but not initiallized
    object of the Aggregate class. These can be used for testing and 
    demonstration. There are several types of aggregates available, 
    distinguished by the `name` argument of the constructor.
        
        
    TestAggregates Provided 
    -----------------------
    
    Below we list the valid values for the `name` argument of the TestAggregate
    constructor:
                
    dimer-2 :
        Dimer of two-level molecules, with positions in space
        and transition dipole moments specified. No environment
        is defined.
        
    dimer-2-env :
        Dimer of two-level molecules, with positions in space and
        transition dipole moments specified. For each molecule
        we define energy gap correlation function (energy gao 
        correlation functions on different sites are not correlated). 

    homodimer-2 :
        Homo-dimer of two-level molecules (molecules with the same energy 
        gaps), with positions in space
        and transition dipole moments specified. No environment
        is defined.
        
    homodimer-2-env :
        Homo-dimer of two-level molecules, with positions in space and
        transition dipole moments specified. For each molecule
        we define energy gap correlation function (energy gao 
        correlation functions on different sites are not correlated).
        
    Class Details
    -------------

"""

import numpy

from .aggregates import Aggregate
from .molecules import Molecule
from .modes import Mode
from ..core.units import convert
from ..core.time import TimeAxis
from ..qm.corfunctions.correlationfunctions import CorrelationFunction
from ..core.managers import energy_units 

[docs]class TestAggregate(Aggregate): """Class to support tests on Aggregate class Parameters ---------- name : str Name characterizing the test aggregate. Examples -------- General dimers >>> # Dimer of two-level systems >>> tagg = TestAggregate(name="dimer-2") >>> tagg.build() >>> tagg.has_SystemBathInteraction() False >>> # Dimer of two-level systems with an environment >>> tagg = TestAggregate(name="dimer-2-env") >>> tagg.build() >>> tagg.has_SystemBathInteraction() True Homo-dimers >>> # Dimer of two-level systems >>> tagg = TestAggregate(name="homodimer-2") >>> tagg.build() >>> tagg.has_SystemBathInteraction() False >>> # Dimer of two-level systems with an environment >>> tagg = TestAggregate(name="homodimer-2-env") >>> tagg.build() >>> tagg.has_SystemBathInteraction() True >>> # Trimer of two-level systems without an environment >>> tagg = TestAggregate(name="trimer-2") >>> tagg.build() >>> tagg.has_SystemBathInteraction() False """ def __init__(self, name=None): """ Some more doctests >>> TestAggregate() Traceback (most recent call last): ... Exception: Aggregate name not specified """ if name is None: raise Exception("Aggregate name not specified") # # Test dimer # if name == "dimer-2-env": m1, m2 = self._molecules(N=2, nst=2) # set their environment time = TimeAxis(0, 1000, 1.0) cpar = dict(ftype="OverdampedBrownian", reorg=20, cortime=100, T=300) with energy_units("1/cm"): cfce = CorrelationFunction(time, cpar) m1.set_transition_environment((0, 1), cfce) m2.set_transition_environment((0, 1), cfce) super().__init__(molecules=[m1, m2]) elif name == "trimer-2-env": m1, m2, m3 = self._molecules(N=3, nst=2) # set their environment time = TimeAxis(0, 1000, 1.0) cpar = dict(ftype="OverdampedBrownian", reorg=20, cortime=100, T=300) with energy_units("1/cm"): cfce = CorrelationFunction(time, cpar) m1.set_transition_environment((0, 1), cfce) m2.set_transition_environment((0, 1), cfce) m3.set_transition_environment((0, 1), cfce) super().__init__(molecules=[m1, m2, m3]) elif name == "dimer-2": m1, m2 = self._molecules(N=2, nst=2) # set their environment # nothing here super().__init__(molecules=[m1, m2]) elif name == "trimer-2": m1, m2, m3 = self._molecules(N=3, nst=2, homo=False) super().__init__(molecules=[m1, m2, m3]) elif name == "homodimer-2-env": m1, m2 = self._molecules(N=2, nst=2, homo=True) # set their environment time = TimeAxis(0, 1000, 1.0) cpar = dict(ftype="OverdampedBrownian", reorg=20, cortime=100, T=300) with energy_units("1/cm"): cfce = CorrelationFunction(time, cpar) m1.set_transition_environment((0, 1), cfce) m2.set_transition_environment((0, 1), cfce) super().__init__(molecules=[m1, m2]) elif name == "homodimer-2": m1, m2 = self._molecules(N=2, nst=2, homo=True) # set their environment # nothing here super().__init__(molecules=[m1, m2]) elif name == "dimer-2-vib": m1, m2 = self._molecules(N=2, nst=2) with energy_units("1/cm"): mod1 = Mode(100.0) m1.add_Mode(mod1) mod1.set_HR(1,0.1) mod2 = Mode(100.0) m2.add_Mode(mod2) mod2.set_HR(1,0.1) super().__init__(molecules=[m1, m2]) def _molecules(self, N, nst, homo=False): """Creates molecules to be filled into Aggregate Testing that None is returned for wrong arguments >>> tagg = TestAggregate("dimer-2") >>> mols = tagg._molecules(3, 5) >>> print(mols) None """ if (N == 2) and (nst == 2): nstates = nst # check inputs if nstates != 2: raise Exception() # set parameters gap1 = convert(12000,"1/cm", to="int") energies1 = numpy.zeros(nstates) for s in range(nstates): energies1[s] = s*gap1 if homo: gap2 = convert(12000,"1/cm", to="int") else: gap2 = convert(12300,"1/cm", to="int") energies2 = numpy.zeros(nstates) for s in range(nstates): energies2[s] = s*gap2 # molecules m1 = Molecule(elenergies=energies1) m2 = Molecule(elenergies=energies2) # set transition dipole moments dip1 = [0.0, 2.0, 0.0] dip2 = [0.0, 1.3, 1.4] m1.set_dipole(0, 1, dip1) m2.set_dipole(0, 1, dip2) #set molecular positions r1 = [0.0, 0.0, 0.0] r2 = [5.0, 0.0, 0.0] m1.position = r1 m2.position = r2 return [m1, m2] elif (N == 3) and (nst == 2): nstates = nst # check inputs if nstates != 2: raise Exception() # set parameters gap1 = convert(12000, "1/cm", to="int") energies1 = numpy.zeros(nstates) for s in range(nstates): energies1[s] = s*gap1 if homo: gap2 = convert(12000, "1/cm", to="int") gap3 = gap2 else: gap2 = convert(12300, "1/cm", to="int") gap3 = convert(12350, "1/cm", to="int") energies2 = numpy.zeros(nstates) energies3 = numpy.zeros(nstates) for s in range(nstates): energies2[s] = s*gap2 energies3[s] = s*gap3 # molecules m1 = Molecule(elenergies=energies1) m2 = Molecule(elenergies=energies2) m3 = Molecule(elenergies=energies3) # set transition dipole moments dip1 = [0.0, 2.0, 0.0] dip2 = [0.0, 1.3, 1.4] dip3 = [1.0, 1.2, 0.0] m1.set_dipole(0, 1, dip1) m2.set_dipole(0, 1, dip2) m3.set_dipole(0, 1, dip3) #set molecular positions r1 = [0.0, 0.0, 0.0] r2 = [5.0, 0.0, 0.0] r3 = [0.0, 0.0, 5.0] m1.position = r1 m2.position = r2 m3.position = r3 return [m1, m2, m3] else: return None