예제 #1
0
    def test_set_resonance_coupling_matrix(self):
        """(Aggregate) Testing setting the whole resonance coupling matrix
        
        """
        agg = TestAggregate(name="dimer-2-env")

        mat = [[0.0, 1.0],
               [1.0, 0.0]]
        
        agg.set_resonance_coupling_matrix(mat)
        self.assertAlmostEqual(agg.resonance_coupling[1,0], 1.0)
        self.assertAlmostEqual(agg.resonance_coupling[0,1], 1.0)
        self.assertAlmostEqual(agg.resonance_coupling[0,0], 0.0)
        self.assertAlmostEqual(agg.resonance_coupling[1,1], 0.0)

        mat = ((0.0, 500.0),
               (500.0, 0.0))
        
        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling_matrix(mat)

        inint = qr.convert(500, "1/cm", "int")
        self.assertAlmostEqual(agg.resonance_coupling[1,0], inint)
        self.assertAlmostEqual(agg.resonance_coupling[0,1], inint)
        self.assertAlmostEqual(agg.resonance_coupling[0,0], 0.0)
        self.assertAlmostEqual(agg.resonance_coupling[1,1], 0.0)
예제 #2
0
def set_cor_func(for_agg, params, ax_len = 10000):

    ax_length = ax_len
    # Needs to have small step for the dynamics to converge
    t_ax_sd = qr.TimeAxis(0.0, ax_length, 1)
    db = SpectralDensityDB()

    # Parameters for spectral density. ODBO, Renger or Silbey
    params = params
    with qr.energy_units('1/cm'):
        sd_low_freq = qr.SpectralDensity(t_ax_sd, params)

    reorg = qr.convert(sd_low_freq.measure_reorganization_energy(), "int", "1/cm")
    print("spectral density reorg -", reorg)

    # Adding the high freq modes
    sd_high_freq = db.get_SpectralDensity(t_ax_sd, "Wendling_JPCB_104_2000_5825")
    ax = sd_low_freq.axis
    sd_high_freq.axis = ax
    sd_tot = sd_low_freq + sd_high_freq

    cf = sd_tot.get_CorrelationFunction(temperature=params['T'], ta=t_ax_sd)
    # Assigning the correlation function to the list of molecules
    for mol in for_agg:
        mol.set_transition_environment((0,1),cf)
예제 #3
0
 def test_set_resonance_coupling(self):        
     """(Aggregate) Testing resonance coupling setting with different units
     
     """
     agg = TestAggregate(name="dimer-2-env")
     agg.init_coupling_matrix()        
     
     agg.set_resonance_coupling(0, 1, 1.0)
     self.assertAlmostEqual(1.0, agg.resonance_coupling[0,1])
     self.assertAlmostEqual(1.0, agg.resonance_coupling[1,0])
     
     with qr.energy_units("1/cm"):
         agg.set_resonance_coupling(0, 1, 100.0)
     self.assertAlmostEqual(qr.convert(100.0, "1/cm", "int"),
                            agg.resonance_coupling[0,1])
     self.assertAlmostEqual(qr.convert(100.0, "1/cm", "int"),
                            agg.resonance_coupling[1,0])
예제 #4
0
    def test_set_resonance_coupling(self):
        """(Aggregate) Testing resonance coupling setting with different units
        
        """
        agg = TestAggregate(name="dimer-2-env")
        agg.init_coupling_matrix()

        agg.set_resonance_coupling(0, 1, 1.0)
        self.assertAlmostEqual(1.0, agg.resonance_coupling[0, 1])
        self.assertAlmostEqual(1.0, agg.resonance_coupling[1, 0])

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling(0, 1, 100.0)
        self.assertAlmostEqual(qr.convert(100.0, "1/cm", "int"),
                               agg.resonance_coupling[0, 1])
        self.assertAlmostEqual(qr.convert(100.0, "1/cm", "int"),
                               agg.resonance_coupling[1, 0])
예제 #5
0
    def test_dipole_dipole_coupling(self):
        """(Aggregate) Testing dipole-dipole coupling calculation

        """
        agg = TestAggregate(name="dimer-2-env")

        coup1 = agg.dipole_dipole_coupling(0, 1)
        coup2 = agg.dipole_dipole_coupling(0, 1, epsr=2.0)
        self.assertAlmostEqual(coup1, coup2 * 2.0)

        with qr.energy_units("1/cm"):
            coup = agg.dipole_dipole_coupling(0, 1)
        self.assertAlmostEqual(qr.convert(coup1, "int", "1/cm"), coup)
예제 #6
0
    def test_get_resonance_coupling(self):
        """(Aggregate) Testing resonance coupling retrieval in different units
        
        """
        agg = TestAggregate(name="dimer-2-env")
        agg.init_coupling_matrix()        
        agg.set_resonance_coupling(0, 1, 1.0)

        coup = agg.get_resonance_coupling(1,0)
        self.assertAlmostEqual(coup, 1.0)

        with qr.energy_units("1/cm"):
            coup = agg.get_resonance_coupling(1,0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "1/cm"))
        
        with qr.energy_units("eV"):
            coup = agg.get_resonance_coupling(1,0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "eV"))
        
        with qr.energy_units("THz"):
            coup = agg.get_resonance_coupling(1,0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "THz"))
예제 #7
0
    def test_dipole_dipole_coupling(self):
        """(Aggregate) Testing dipole-dipole coupling calculation

        """
        agg = TestAggregate(name="dimer-2-env")

        coup1 = agg.dipole_dipole_coupling(0,1)
        coup2 = agg.dipole_dipole_coupling(0,1, epsr=2.0)
        self.assertAlmostEqual(coup1, coup2*2.0)
        
        with qr.energy_units("1/cm"):
            coup = agg.dipole_dipole_coupling(0,1)
        self.assertAlmostEqual(qr.convert(coup1,"int","1/cm"), coup)
예제 #8
0
    def test_get_resonance_coupling(self):
        """(Aggregate) Testing resonance coupling retrieval in different units
        
        """
        agg = TestAggregate(name="dimer-2-env")
        agg.init_coupling_matrix()
        agg.set_resonance_coupling(0, 1, 1.0)

        coup = agg.get_resonance_coupling(1, 0)
        self.assertAlmostEqual(coup, 1.0)

        with qr.energy_units("1/cm"):
            coup = agg.get_resonance_coupling(1, 0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "1/cm"))

        with qr.energy_units("eV"):
            coup = agg.get_resonance_coupling(1, 0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "eV"))

        with qr.energy_units("THz"):
            coup = agg.get_resonance_coupling(1, 0)
        self.assertAlmostEqual(coup, qr.convert(1.0, "int", "THz"))
예제 #9
0
    def test_set_resonance_coupling_matrix(self):
        """(Aggregate) Testing setting the whole resonance coupling matrix
        
        """
        agg = TestAggregate(name="dimer-2-env")

        mat = [[0.0, 1.0], [1.0, 0.0]]

        agg.set_resonance_coupling_matrix(mat)
        self.assertAlmostEqual(agg.resonance_coupling[1, 0], 1.0)
        self.assertAlmostEqual(agg.resonance_coupling[0, 1], 1.0)
        self.assertAlmostEqual(agg.resonance_coupling[0, 0], 0.0)
        self.assertAlmostEqual(agg.resonance_coupling[1, 1], 0.0)

        mat = ((0.0, 500.0), (500.0, 0.0))

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling_matrix(mat)

        inint = qr.convert(500, "1/cm", "int")
        self.assertAlmostEqual(agg.resonance_coupling[1, 0], inint)
        self.assertAlmostEqual(agg.resonance_coupling[0, 1], inint)
        self.assertAlmostEqual(agg.resonance_coupling[0, 0], 0.0)
        self.assertAlmostEqual(agg.resonance_coupling[1, 1], 0.0)
예제 #10
0
def run(omega,
        HR,
        dE,
        JJ,
        rate,
        E0,
        vib_loc="up",
        use_vib=True,
        detailed_balance=False,
        temperature=77.0,
        stype=qr.signal_REPH,
        save_eUt=False,
        t2_save_pathways=[],
        dname=None,
        trimer=None,
        disE=None):
    """Runs a complete set of simulations for a single set of parameters


    If disE is not None it tries to run averaging over Gaussian energetic
    disorder.

    """
    if dname is None:
        dname = "sim_" + vib_loc

    use_trimer = trimer["useit"]
    rate_sp = trimer["rate"]

    #
    #  PARAMETERS FROM INPUT FILE
    #
    dip1 = INP.dip1  # [1.5, 0.0, 0.0]
    dip2 = INP.dip2  # [-1.0, -1.0, 0.0]
    width = INP.feature_width  # 100.0
    width2 = INP.feature_width2

    normalize_maps_to_maximu = False
    trim_maps = False

    units = "1/cm"
    with qr.energy_units(units):

        data_descr = "_dO="+str(dE)+"_omega="+str(omega)+ \
                     "_HR="+str(HR)+"_J="+str(JJ)

        if use_vib:
            sys_char = "_vib"
        else:
            sys_char = "_ele"
        data_ext = sys_char + ".png"
        obj_ext = sys_char + ".qrp"

    # parameters of the SP
    if use_trimer:
        E2 = trimer["E2"]
        epsa = (E0 + E2) / 2.0
        DE = trimer["DE"]
        J2 = 0.5 * numpy.sqrt(((E0 - E2)**2) - (DE**2))
        ESP2 = epsa + DE / 2.0
        ESP1 = epsa - DE / 2.0

    #
    #   Model system is a dimer of molecules
    #
    with qr.energy_units("1/cm"):

        if not use_trimer:

            if disE is not None:
                mol1 = qr.Molecule([0.0, E0 + disE[0]])
                mol2 = qr.Molecule([0.0, E0 + dE + disE[1]])
                print("Monomer 1 energy:", E0 + disE[0], "1/cm")
                print("Monomer 2 energy:", E0 + dE + disE[1], "1/cm")
            else:
                mol1 = qr.Molecule([0.0, E0])
                mol2 = qr.Molecule([0.0, E0 + dE])
                print("Monomer 1 energy:", E0, "1/cm")
                print("Monomer 2 energy:", E0 + dE, "1/cm")
        else:

            if disE is not None:
                mol1 = qr.Molecule([0.0, ESP2 + disE[0]])
                mol2 = qr.Molecule([0.0, E0 + dE + disE[1]])
                print("Monomer 1 (SP_high) energy:", ESP2 + disE[0], "1/cm")
                print("Monomer 2 (B) energy:", E0 + dE + disE[1], "1/cm")
            else:
                mol1 = qr.Molecule([0.0, ESP2])
                mol2 = qr.Molecule([0.0, E0 + dE])
                print("Monomer 1 (SP_high) energy:", ESP2, "1/cm")
                print("Monomer 2 (B) energy:", E0 + dE, "1/cm")
            if disE is not None:
                mol3 = qr.Molecule([0.0, ESP1 + disE[2]])
                print("Monomer 3 (SP_low) energy:", ESP1 + disE[2], "1/cm")
            else:
                mol3 = qr.Molecule([0.0, ESP1])
                print("Monomer 3 (SP_low) energy:", ESP1, "1/cm")
            mol3.set_transition_width((0, 1), width2)
            mol3.set_dipole(0, 1, trimer["dipsp"])

        mol1.set_transition_width((0, 1), width2)
        mol1.set_dipole(0, 1, dip1)

        mol2.set_transition_width((0, 1), width)
        mol2.set_dipole(0, 1, dip2)

    if use_trimer:
        agg = qr.Aggregate([mol1, mol2, mol3])
    else:
        agg = qr.Aggregate([mol1, mol2])

    if use_trimer:

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling(0, 1, JJ)
            print("B - SP_high coupling:", JJ, "1/cm")
            agg.set_resonance_coupling(0, 2, J2)
            print("SP coupling:", J2, "1/cm")

    else:

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling(0, 1, JJ)

    #
    # Electronic only aggregate
    #
    agg_el = agg.deepcopy()

    #
    # if nuclear vibrations are to be added, do it here
    #
    if use_vib:

        with qr.energy_units("1/cm"):
            mod1 = qr.Mode(omega)
            mod2 = qr.Mode(omega)

        if vib_loc == "down":
            set_vib = [True, False]
        elif vib_loc == "up":
            set_vib = [False, True]
        elif vib_loc == "both":
            set_vib = [True, True]
        else:
            raise Exception("Unknown location of the vibrations")

        if set_vib[0]:
            print("Vibrations set for SP_high molecule")
            mol1.add_Mode(mod1)
            mod1.set_nmax(0, INP.vibmode["no_g_vib"])
            mod1.set_nmax(1, INP.vibmode["no_e_vib"])
            mod1.set_HR(1, HR)

        if set_vib[1]:
            print("Vibrations set for B molecule")
            mol2.add_Mode(mod2)
            mod2.set_nmax(0, INP.vibmode["no_g_vib"])
            mod2.set_nmax(1, INP.vibmode["no_e_vib"])
            mod2.set_HR(1, HR)

    #
    # Before we build the aggregate, we make its copy to have an unbuilt version
    #
    agg3 = agg.deepcopy()
    aggA = agg.deepcopy()

    #
    # here we build the complete aggregate and its electronic only version
    #
    agg.build(mult=1)
    agg_el.build(mult=1)
    aggA.build(mult=1)

    # total Hamiltonian
    HH = agg.get_Hamiltonian()
    # electronic Hamiltonian
    He = agg_el.get_Hamiltonian()

    #
    # Laboratory setup
    #
    lab = qr.LabSetup()
    lab.set_polarizations(pulse_polarizations=[X, X, X],
                          detection_polarization=X)

    #
    # Time axis for the calculation of excited state evolution
    #
    t2_N_steps = INP.t2_N_steps
    t2_time_step = INP.t2_time_step
    time2 = qr.TimeAxis(0.0, t2_N_steps, t2_time_step)

    #
    # Containers for 2D maps with positive and negative frequencies
    #
    cont_p = qr.TwoDResponseContainer(t2axis=time2)
    cont_m = qr.TwoDResponseContainer(t2axis=time2)
    cont_tot = qr.TwoDResponseContainer(t2axis=time2)

    #
    # spectra will be indexed by the times in the time axis `time2`
    #
    cont_p.use_indexing_type(time2)
    cont_m.use_indexing_type(time2)
    cont_tot.use_indexing_type(time2)

    #
    # We define two-time axes, which will be FFTed and will define
    # the omega_1 and omega_3 axes of the 2D spectrum
    #
    t1_N_steps = INP.t1_N_steps
    t1_time_step = INP.t1_time_step
    t3_N_steps = INP.t3_N_steps
    t3_time_step = INP.t3_time_step
    t1axis = qr.TimeAxis(0.0, t1_N_steps, t1_time_step)
    t3axis = qr.TimeAxis(0.0, t3_N_steps, t3_time_step)

    #
    # This calculator calculated 2D spectra from the effective width
    #
    msc = qr.MockTwoDResponseCalculator(t1axis, time2, t3axis)
    with qr.energy_units("1/cm"):
        msc.bootstrap(rwa=E0, shape="Gaussian")

    #
    # System-bath interaction including vibrational states
    #
    operators = []
    rates = []

    print("Relaxation rates: ", rate, rate_sp, "1/fs")

    with qr.eigenbasis_of(He):

        if use_trimer:
            if He.data[3, 3] < He.data[2, 2]:
                Exception("Electronic states not orderred!")
            operators.append(qr.qm.ProjectionOperator(2, 3, dim=He.dim))
            with qr.energy_units("1/cm"):
                print("2 <- 3 : energies = ", He.data[2, 2], He.data[3, 3],
                      "1/cm")
            rates.append(rate)
            print("Transfer time 2 <- 3:", 1.0 / rate, "fs")

            if He.data[2, 2] < He.data[1, 1]:
                Exception("Electronic states not orderred!")
            operators.append(qr.qm.ProjectionOperator(1, 2, dim=He.dim))
            with qr.energy_units("1/cm"):
                print("1 <- 2 : energies = ", He.data[1, 1], He.data[2, 2],
                      "1/cm")
            rates.append(rate_sp)
            print("Transfer time 1 <- 2", 1.0 / rate_sp, "fs")

        else:

            if He.data[2, 2] < He.data[1, 1]:
                Exception("Electronic states not orderred!")
            operators.append(qr.qm.ProjectionOperator(1, 2, dim=He.dim))
            with qr.energy_units("1/cm"):
                print("1 <- 2 : energies = ", He.data[1, 1], He.data[2, 2],
                      "1/cm")
            rates.append(rate_sp)
            print("Transfer time 1 <- 2", 1.0 / rate, "fs")

    # include detailed balace
    if detailed_balance:
        if use_trimer:
            with qr.eigenbasis_of(He):
                T = temperature  #77.0
                Den = (He.data[3, 3] - He.data[2, 2]) / (kB_int * T)
                operators.append(qr.qm.ProjectionOperator(3, 2, dim=He.dim))
                thermal_fac = numpy.exp(-Den)
                rates.append(rate * thermal_fac)
                Den = (He.data[2, 2] - He.data[1, 1]) / (kB_int * T)
                operators.append(qr.qm.ProjectionOperator(2, 1, dim=He.dim))
                thermal_fac = numpy.exp(-Den)
                rates.append(rate_sp * thermal_fac)

        else:

            with qr.eigenbasis_of(He):
                T = temperature  #77.0
                Den = (He.data[2, 2] - He.data[1, 1]) / (kB_int * T)
                operators.append(qr.qm.ProjectionOperator(2, 1, dim=He.dim))
                thermal_fac = numpy.exp(-Den)
            rates.append(rate * thermal_fac)

    sbi = qr.qm.SystemBathInteraction(sys_operators=operators, rates=rates)
    sbi.set_system(agg)

    #
    # Lindblad form for relaxation
    #
    LF = qr.qm.ElectronicLindbladForm(HH, sbi, as_operators=True)

    #
    # Pure dephasing
    #
    p_deph = qr.qm.ElectronicPureDephasing(agg, dtype="Gaussian")

    # we simplify calculations by converting dephasing to
    # corresponding Lorentzian form
    p_deph.convert_to("Lorentzian")

    eUt = qr.qm.EvolutionSuperOperator(time2,
                                       HH,
                                       relt=LF,
                                       pdeph=p_deph,
                                       mode="all")
    eUt.set_dense_dt(INP.fine_splitting)

    print("---")

    #
    # We calculate evolution superoperator
    #
    eUt.calculate(show_progress=False)

    # save the evolution operator
    if save_eUt:
        eut_name = os.path.join(
            dname, "eUt" + "_omega2=" + str(omega) + data_descr + obj_ext)
        eUt.save(eut_name)

    #
    # Prepare aggregate with all states (including 2-EX band)
    #
    agg3.build(mult=2)
    agg3.diagonalize()

    agg_el.diagonalize()
    print("")
    print("Square of the transition dipoles")
    print(agg_el.D2)
    print("")
    print("---")

    #
    # calculation of absorption spectrum
    #
    time1 = qr.TimeAxis(0.0, 1000, 5.0)
    absc = qr.MockAbsSpectrumCalculator(time1, system=aggA)
    with qr.energy_units("1/cm"):
        absc.bootstrap(rwa=E0)

    spctrm = absc.calculate()
    spctrm.normalize2()

    with qr.energy_units("1/cm"):
        spctrm.plot(show=False, axis=[10500.0, 13500.0, 0.0, 1.1])
        spctrm.savefig(os.path.join(dname, "abs.png"))
        spctrm.save_data(os.path.join(dname, "abs.dat"))

    pways = dict()

    olow_cm = omega - INP.omega_uncertainty / 2.0
    ohigh_cm = omega + INP.omega_uncertainty / 2.0
    olow = qr.convert(olow_cm, "1/cm", "int")
    ohigh = qr.convert(ohigh_cm, "1/cm", "int")

    for t2 in time2.data:

        # this could save some memory of pathways become too big
        pways = dict()

        print("T2 =", t2, "fs (of T2_max =", time2.max, "fs)")

        twod = msc.calculate_one_system(t2,
                                        agg3,
                                        eUt,
                                        lab,
                                        pways=pways,
                                        dtol=1.0e-12,
                                        selection=[["omega2", [olow, ohigh]]])
        pws = pways[str(t2)]
        npa = len(pws)
        has_R = False
        has_NR = False
        for pw in pws:
            if pw.pathway_type == "NR":
                has_NR = True
            elif pw.pathway_type == "R":
                has_R = True

        if t2 in t2_save_pathways:
            pws_name = os.path.join(
                dname, "pws_t2=" + str(t2) + "_omega2=" + str(omega) +
                data_descr + obj_ext)
            qr.save_parcel(pways[str(t2)], pws_name)

        cont_p.set_spectrum(twod)

        twod = msc.calculate_one_system(t2,
                                        agg3,
                                        eUt,
                                        lab,
                                        pways=pways,
                                        dtol=1.0e-12,
                                        selection=[["omega2", [-ohigh,
                                                               -olow]]])

        pws = pways[str(t2)]
        npa = len(pws)
        #print(" m:", npa)
        has_R = False
        has_NR = False
        for pw in pws:
            if pw.pathway_type == "NR":
                has_NR = True
            elif pw.pathway_type == "R":
                has_R = True

        #print(" R:", has_R, ", NR:", has_NR)

        if t2 in t2_save_pathways:
            pws_name = os.path.join(
                dname, "pws_t2=" + str(t2) + "_omega2=" + str(-omega) +
                data_descr + obj_ext)
            qr.save_parcel(pways[str(t2)], pws_name)

        cont_m.set_spectrum(twod)

        # calculation without pre-selecting pathways
        twod = msc.calculate_one_system(t2,
                                        agg3,
                                        eUt,
                                        lab,
                                        pways=pways,
                                        dtol=1.0e-12)

        cont_tot.set_spectrum(twod)

    # saving total spectrum to a directory for further analysis
    try:
        saveit = INP.total_spectrum["save_it"]
    except:
        saveit = False

    if saveit:
        try:
            dform = INP.total_spectrum["data_format"]
        except:
            dform = "dat"
        try:
            stp = INP.total_spectrum["spectra_type"]
            if stp == "TOTL":
                stype = qr.signal_TOTL
            elif stp == "REPH":
                stype = qr.signal_REPH
            elif stp == "NONR":
                stype = qr.signal_NONR
            else:
                raise Exception("Wrong signal type")
        except:
            stype = qr.signal_REPH

        save_spectra(cont_tot, ext=dform, dir=dname, stype=stype)

    #
    # Save aggregate when a single calculation is done
    #
    if save_eUt:
        fname = os.path.join(dname, "aggregate.qrp")
        agg3.save(fname)

    #
    # Window function for subsequenty FFT
    #
    window = func.Tukey(time2, r=INP.tukey_window_r, sym=False)

    #
    # FFT with the window function
    #
    # Specify REPH, NONR or `total` to get different types of spectra
    #
    print("Calculating FFT of the 2D maps")
    #fcont = cont.fft(window=window, dtype=stype) #, dpart="real", offset=0.0)

    fcont_p_re = cont_p.fft(window=window, dtype=qr.signal_REPH)
    fcont_p_nr = cont_p.fft(window=window, dtype=qr.signal_NONR)
    fcont_p_to = cont_p.fft(window=window, dtype=qr.signal_TOTL)

    if normalize_maps_to_maximu:
        fcont_p_re.normalize2(dpart=qr.part_ABS)
        fcont_p_nr.normalize2(dpart=qr.part_ABS)
        fcont_p_to.normalize2(dpart=qr.part_ABS)

    fcont_m_re = cont_m.fft(window=window, dtype=qr.signal_REPH)
    fcont_m_nr = cont_m.fft(window=window, dtype=qr.signal_NONR)
    fcont_m_to = cont_m.fft(window=window, dtype=qr.signal_TOTL)

    if normalize_maps_to_maximu:
        fcont_m_re.normalize2(dpart=qr.part_ABS)
        fcont_m_nr.normalize2(dpart=qr.part_ABS)
        fcont_m_to.normalize2(dpart=qr.part_ABS)

    if trim_maps:
        twin = INP.trim_maps_to
        with qr.energy_units("1/cm"):
            fcont_p_re.trimall_to(window=twin)
            fcont_p_nr.trimall_to(window=twin)
            fcont_p_to.trimall_to(window=twin)

    show_omega = omega

    with qr.frequency_units("1/cm"):
        sp1_p_re, show_Npoint1 = fcont_p_re.get_nearest(show_omega)
        sp2_p_re, show_Npoint2 = fcont_p_re.get_nearest(-show_omega)
        sp1_p_nr, show_Npoint1 = fcont_p_nr.get_nearest(show_omega)
        sp2_p_nr, show_Npoint2 = fcont_p_nr.get_nearest(-show_omega)
        sp1_p_to, show_Npoint1 = fcont_p_to.get_nearest(show_omega)
        sp2_p_to, show_Npoint2 = fcont_p_to.get_nearest(-show_omega)
        sp1_m_re, show_Npoint1 = fcont_m_re.get_nearest(show_omega)
        sp2_m_re, show_Npoint2 = fcont_m_re.get_nearest(-show_omega)
        sp1_m_nr, show_Npoint1 = fcont_m_nr.get_nearest(show_omega)
        sp2_m_nr, show_Npoint2 = fcont_m_nr.get_nearest(-show_omega)
        sp1_m_to, show_Npoint1 = fcont_m_to.get_nearest(show_omega)
        sp2_m_to, show_Npoint2 = fcont_m_to.get_nearest(-show_omega)

    sstm = platform.system()
    #print(sstm)
    if sstm != "Windows":
        import resource
        memo = resource.getrusage(
            resource.RUSAGE_SELF).ru_maxrss / (1024 * 1024)
        print("Memory usage: ", memo, "in MB")

    return (sp1_p_re, sp1_p_nr, sp2_m_re, sp2_m_nr)
예제 #11
0
# Aggregate with vibrational states, Hamiltonian generated up to single
# exciton states in a Two-particle approximation
# This object is used for calculation of dynamics
#
agg.build(mult=1, vibgen_approx="TPA")

#
# agg2 object will be used for calculation of 2D spectra
# so it needs to know how to represent the spectra (what width it should have).
# It also has to be built with
# two-exciton states (in two-particle approximation)
#

for mol_name in transition_widths:
    
    width = qr.convert(transition_widths[mol_name], "1/cm", "int")
    mol = agg2.get_Molecule_by_name(mol_name)
    mol.set_transition_width((0,1), width)

print("Aggregate has ", agg2.nmono, "single excited electronic states")

agg2.build(mult=2, vibgen_approx="TPA")

print("and ", agg2.Ntot, " (electro-vibrational) states in total")
print("Number of single exciton states :", agg2.Nb[0]+agg2.Nb[1])


qr.save_parcel(agg2, os.path.join(pre_out,"agg2_built.qrp"))

#
# Electronic aggregate is built with single exciton states only
예제 #12
0
import numpy

import quantarhei as qr

qr.Manager().gen_conf.legacy_relaxation = True

print("Preparing a model system:")

with qr.energy_units("1/cm"):
    mol1 = qr.Molecule([0.0, 12010])
    mol2 = qr.Molecule([0.0, 12000])
    mol3 = qr.Molecule([0.0, 12100])
    mol4 = qr.Molecule([0.0, 12110])

agg = qr.Aggregate([mol1, mol2, mol3, mol4])
agg.set_resonance_coupling(2, 3, qr.convert(100.0, "1/cm", "int"))
agg.set_resonance_coupling(1, 3, qr.convert(100.0, "1/cm", "int"))
agg.set_resonance_coupling(1, 2, qr.convert(0.0, "1/cm", "int"))

qr.save_parcel(agg, "agg.qrp")
agg2 = qr.load_parcel("agg.qrp")
agg2.build()

H = agg2.get_Hamiltonian()

print("...done")

print("Setting up Lindblad form relaxation:")
Ndim = 5
with qr.eigenbasis_of(H):
    K12 = qr.qm.ProjectionOperator(1, 2, dim=Ndim)
    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)
예제 #14
0
# Create an aggregate
#
agg = qr.Aggregate(molecules=[mol])

agg.build()

#
# Time axes and the calculator
#
t1axis = qr.TimeAxis(0.0, 1000, 10.0)
t3axis = qr.TimeAxis(0.0, 1000, 10.0)
t2axis = qr.TimeAxis(0.0, Nt2, dt2)

# FIXME: TwoDResponseCalculator
msc = qr.MockTwoDResponseCalculator(t1axis, t2axis, t3axis)
msc.bootstrap(rwa=qr.convert(E1,"1/cm","int"), 
              all_positive=False, shape="Gaussian")

#
# Laboratory setup
#

lab = LabSetup()
lab.set_polarizations(pulse_polarizations=[X,X,X], detection_polarization=X)

#
# Hamiltonian is required
#
H = agg.get_Hamiltonian()

#
예제 #15
0
with qr.energy_units("1/cm"):
    agg.set_resonance_coupling_matrix(J_Matrix[0:3, 0:3])

#agg.save("RC_Model_40_4_adjusted_CT_no_environment_unbuilt.hdf5")
qr.save_parcel(
    agg,
    os.path.join(pre_out,
                 "RC_Model_40_4_adjusted_CT_no_environment_unbuilt.qrp"))

# In[3]:

# check that units were set correctly
rc = agg.resonance_coupling[1, 0]
with qr.energy_units("1/cm"):
    print(qr.convert(rc, "int"))

with qr.energy_units("1/cm"):
    print(agg.get_resonance_coupling(1, 0))

# In[4]:

# Bath correlation function
time = qr.TimeAxis(0.0, 1000, 1.0)

cfA_params = dict(ftype="OverdampedBrownian",
                  reorg=190,
                  cortime=80,
                  T=77,
                  matsubara=100)
cfH_params = dict(ftype="OverdampedBrownian",
예제 #16
0
#

# In[37]:

frac_electronic.report_on_expansion(3, N=4)

#
# State 3 is a clear anti-symmetric mixture of P(+) and B
#

# In[38]:

N1 = frac_electronic.Nbe[1]
print("Energies in 1/cm:")
print([
    qr.convert(frac_electronic.HH[i, i], "int", "1/cm")
    for i in range(1, N1 + 1)
])

# In[39]:

#
# Transition dipoles square
#
print("Transition dipoles square:")
print(frac_electronic.D2[1:N1 + 1, 0])

# In[40]:

#frac.save("fraction_45_2_vibrations_CT_built.hdf5")
qr.save_parcel(frac,
예제 #17
0
def run(omega, HR, dE, JJ, rate, vib_loc="up", use_vib=True,
        stype=qr.signal_REPH, make_movie=False):
    """Runs a complete set of simulations for a single set of parameters
    
    
    
    """

    #
    #  FIXED PARAMETERS
    #
    E0 = 10000.0
    dip1 = [1.5, 0.0, 0.0]
    dip2 = [-1.0, -1.0, 0.0]
    width = 100.0
    #rate = 1.0/50.0
    
    normalize_maps_to_maximu = False
    trim_maps = False
    
    units = "1/cm"
    with qr.energy_units(units):
        
        data_descr = "_dO="+str(dE-omega)+"_HR="+str(HR)+"_J="+str(JJ)
        
        if use_vib:
            sys_char = "_vib"
        else:
            sys_char = "_ele"
        data_ext = sys_char+".png"
        obj_ext = sys_char+".qrp"
        
    #
    #   Model system is a dimer of molecules
    #
    with qr.energy_units("1/cm"):
        mol1 = qr.Molecule([0.0, E0])
        mol2 = qr.Molecule([0.0, E0+dE])
        
        mod1 = qr.Mode(omega)
        mod2 = qr.Mode(omega)
    
    mol1.set_transition_width((0,1), qr.convert(width, "1/cm", "int"))
    mol1.set_dipole(0,1, dip1)
    
    mol2.set_transition_width((0,1), qr.convert(width, "1/cm", "int"))
    mol2.set_dipole(0,1, dip2)
    
    agg = qr.Aggregate([mol1, mol2])
    
    with qr.energy_units("1/cm"):
        agg.set_resonance_coupling(0,1,JJ)
    
    #
    # Electronic only aggregate
    #
    agg_el = agg.deepcopy()
        
    #
    # if nuclear vibrations are to be added, do it here
    #
    if use_vib:
    
        if vib_loc == "down":
            set_vib = [True, False]
        elif vib_loc == "up":
            set_vib = [False, True]
        elif vib_loc == "both":
            set_vib = [True, True]
        else:
            raise Exception("Unknown location of the vibrations")
            
        if set_vib[0]:
            mol1.add_Mode(mod1)
            mod1.set_nmax(0, 3)
            mod1.set_nmax(1, 3)
            mod1.set_HR(1, HR)
        
        if set_vib[1]:
            mol2.add_Mode(mod2)
            mod2.set_nmax(0, 3)
            mod2.set_nmax(1, 3)
            mod2.set_HR(1, HR)
    
    agg3 = agg.deepcopy()
    
    agg.build(mult=1)
    agg_el.build(mult=1)
    
    HH = agg.get_Hamiltonian()
    He = agg_el.get_Hamiltonian()
    
    with qr.energy_units("1/cm"):
        with qr.eigenbasis_of(He):
            Ep_l = He.data[1,1]
            Ep_u = He.data[2,2]

    Ep = numpy.zeros((4,2))
    Ep[0,0] = Ep_l
    Ep[0,1] = Ep_l
    Ep[1,0] = Ep_l
    Ep[1,1] = Ep_u
    Ep[2,0] = Ep_u
    Ep[2,1] = Ep_l
    Ep[3,0] = Ep_u
    Ep[3,1] = Ep_u

        
    #
    # Laboratory setup
    #
    lab = qr.LabSetup()
    lab.set_polarizations(pulse_polarizations=[X,X,X], 
                          detection_polarization=X)
    
    time2 = qr.TimeAxis(0.0, 100, 10.0)
    
    cont_p = qr.TwoDResponseContainer(t2axis=time2)
    cont_m = qr.TwoDResponseContainer(t2axis=time2) 
    #
    # spectra will be indexed by the times in the time axis `time2`
    #
    cont_p.use_indexing_type(time2)
    
    #
    # We define two-time axes, which will be FFTed and will define 
    # the omega_1 and omega_3 axes of the 2D spectrum
    #
    t1_N_steps = 100
    t1_time_step = 10.0
    t3_N_steps = 100
    t3_time_step = 10.0
    t1axis = qr.TimeAxis(0.0, t1_N_steps, t1_time_step)
    t3axis = qr.TimeAxis(0.0, t3_N_steps, t3_time_step)
    
    #
    # This calculator calculated 2D spectra from the effective width 
    #
    msc = qr.MockTwoDResponseCalculator(t1axis, time2, t3axis)
    with qr.energy_units("1/cm"):
        msc.bootstrap(rwa=E0, shape="Gaussian")

    #
    # System-bath interaction including vibrational states
    #
    operators = []
    rates = []
    with qr.eigenbasis_of(He):
        operators.append(qr.qm.ProjectionOperator(1, 2, dim=He.dim))
    rates.append(rate)
    
    sbi = qr.qm.SystemBathInteraction(sys_operators=operators, rates=rates)
    sbi.set_system(agg)
    
    #
    # Liouville form for relaxation
    #
    LF = qr.qm.ElectronicLindbladForm(HH, sbi, as_operators=True)
    
    #
    # Pure dephasing
    #
    p_deph = qr.qm.ElectronicPureDephasing(agg, dtype="Gaussian")
    
    
    eUt = qr.qm.EvolutionSuperOperator(time2, HH, relt=LF, pdeph=p_deph,
                                       mode="all")
    eUt.set_dense_dt(10)
    
    #
    # We calculate evolution superoperator
    #
    eUt.calculate(show_progress=False)
    
    #
    # Prepare aggregate with all states (including 2-EX band)
    #
    agg3.build(mult=2)
    agg3.diagonalize()
    
    pways = dict()
    t2_save_pathways = [300.0]
    
    olow = qr.convert(omega-30.0, "1/cm", "int")
    ohigh = qr.convert(omega+30.0, "1/cm", "int")
    
    for t2 in time2.data:
        
        # this could save some memory of pathways become too big
        pways = dict()
        
        print("t2 =", t2)
        twod = msc.calculate_one_system(t2, agg3, eUt, lab, pways=pways,
                                        selection=[["omega2",[olow, ohigh]]])
    
        print("Number of pathways used for omega2 =",omega,":",
              len(pways[str(t2)]))

        if t2 in t2_save_pathways:
            pws_name = os.path.join("sim_"+vib_loc, "pws_t2="+str(t2)+
                                    "_omega2="+str(omega)+data_descr+data_ext)
            qr.save_parcel(pways[str(t2)], pws_name) 
       
        cont_p.set_spectrum(twod)

        twod = msc.calculate_one_system(t2, agg3, eUt, lab, pways=pways,
                                        selection=[["omega2",[-ohigh, -olow]]])
    
        print("Number of pathways used for omega2 =",-omega,":",
              len(pways[str(t2)]))
        
        if t2 in t2_save_pathways:
            pws_name = os.path.join("sim_"+vib_loc, "pws_t2="+str(t2)+
                                    "_omega2="+str(-omega)+data_descr+data_ext)
            qr.save_parcel(pways[str(t2)], pws_name)
        
        cont_m.set_spectrum(twod)
    
    if make_movie:
        with qr.energy_units("1/cm"):
            cont_p.make_movie("mov.mp4")
     
    fname = os.path.join("sim_"+vib_loc, "pways.qrp")
    qr.save_parcel(pways, fname)
    
    fname = os.path.join("sim_"+vib_loc, "aggregate.qrp")
    agg3.save(fname)
        
    #
    # Window function for subsequenty FFT
    #
    window = func.Tukey(time2, r=0.3, sym=False)
    
    #
    # FFT with the window function
    #
    # Specify REPH, NONR or `total` to get different types of spectra
    #
    print("\nCalculating FFT of the 2D maps")
    #fcont = cont.fft(window=window, dtype=stype) #, dpart="real", offset=0.0)
    
    fcont_p_re = cont_p.fft(window=window, dtype=qr.signal_REPH)
    fcont_p_nr = cont_p.fft(window=window, dtype=qr.signal_NONR)
    fcont_p_to = cont_p.fft(window=window, dtype=qr.signal_TOTL)
    
    if normalize_maps_to_maximu:
        fcont_p_re.normalize2(dpart=qr.part_ABS)
        fcont_p_nr.normalize2(dpart=qr.part_ABS)
        fcont_p_to.normalize2(dpart=qr.part_ABS)
    
    fcont_m_re = cont_m.fft(window=window, dtype=qr.signal_REPH)
    fcont_m_nr = cont_m.fft(window=window, dtype=qr.signal_NONR)
    fcont_m_to = cont_m.fft(window=window, dtype=qr.signal_TOTL)

    if normalize_maps_to_maximu:   
        fcont_m_re.normalize2(dpart=qr.part_ABS)
        fcont_m_nr.normalize2(dpart=qr.part_ABS)
        fcont_m_to.normalize2(dpart=qr.part_ABS)
   
    if trim_maps:
        twin = [9500, 11000, 9500, 11000]
        with qr.energy_units("1/cm"):
            fcont_p_re.trimall_to(window=twin)
            fcont_p_nr.trimall_to(window=twin)
            fcont_p_to.trimall_to(window=twin)
        
    show_omega = omega
    
    #
    # Have a look which frequencies we actually have
    #
#    Ndat = len(fcont_re.axis.data)
#    print("\nNumber of frequency points:", Ndat)
#    print("In 1/cm they are:")
#    with qr.energy_units("1/cm"):
#        for k_i in range(Ndat):
#            print(k_i, fcont_re.axis.data[k_i])
    
    with qr.frequency_units("1/cm"):
        sp1_p_re, show_Npoint1 = fcont_p_re.get_nearest(show_omega)
        sp2_p_re, show_Npoint2 = fcont_p_re.get_nearest(-show_omega)
        sp1_p_nr, show_Npoint1 = fcont_p_nr.get_nearest(show_omega)
        sp2_p_nr, show_Npoint2 = fcont_p_nr.get_nearest(-show_omega)
        sp1_p_to, show_Npoint1 = fcont_p_to.get_nearest(show_omega)
        sp2_p_to, show_Npoint2 = fcont_p_to.get_nearest(-show_omega)
        sp1_m_re, show_Npoint1 = fcont_m_re.get_nearest(show_omega)
        sp2_m_re, show_Npoint2 = fcont_m_re.get_nearest(-show_omega)
        sp1_m_nr, show_Npoint1 = fcont_m_nr.get_nearest(show_omega)
        sp2_m_nr, show_Npoint2 = fcont_m_nr.get_nearest(-show_omega)
        sp1_m_to, show_Npoint1 = fcont_m_to.get_nearest(show_omega)
        sp2_m_to, show_Npoint2 = fcont_m_to.get_nearest(-show_omega)    
        
        
#    units = "1/cm"
#    with qr.energy_units(units):
#        
#        data_descr = "_dO="+str(dE-omega)+"_HR="+str(HR)+"_J="+str(JJ)
#        
#        if use_vib:
#            sys_char = "_vib"
#        else:
#            sys_char = "_ele"
#        data_ext = sys_char+".png"
#        obj_ext = sys_char+".qrp"

    with qr.energy_units(units):


        print("\nPlotting and saving spectrum at frequency:", 
              fcont_p_re.axis.data[show_Npoint1], units)
        
        fftf_1 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=REPH"+"_omega="+str(omega)+data_ext)
        sp1_p_re.plot(Npos_contours=10, spart=qr.part_ABS, 
                      label="Rephasing\n $\omega="+str(omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1], 
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)], 
                      show_diagonal="-k")   
        sp1_p_re.savefig(fftf_1)
        print("... saved into: ", fftf_1)
        fftf_2 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=NONR"+"_omega="+str(omega)+data_ext)
        sp1_p_nr.plot(Npos_contours=10, spart=qr.part_ABS, 
                      label="Non-rephasing\n $\omega="+str(omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1],
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)],
                      show_diagonal="-k")   
        sp1_p_nr.savefig(fftf_2)
        print("... saved into: ", fftf_2)
        fftf_3 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=tot"+"_omega="+str(omega)+data_ext)
        sp1_p_to.plot(Npos_contours=10, spart=qr.part_ABS, 
                      label="Total\n $\omega="+str(omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1],
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)],
                      show_diagonal="-k")   
        sp1_p_to.savefig(fftf_3)
        print("... saved into: ", fftf_3)        
        
        #
        # Point evolutions at the expected peak positions
        #

        if show_plots:

            for ii in range(4):        
                points = fcont_p_re.get_point_evolution(Ep[ii,0], Ep[ii,1],
                                                        fcont_p_re.axis)
                points.apply_to_data(numpy.abs)
                if ii >= 3:
                    points.plot(show=True)
                else:
                    points.plot(show=False)
            
        
        print("\nPlotting and saving spectrum at frequency:", 
              fcont_m_re.axis.data[show_Npoint2], units)
        fftf_4 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=REPH"+"_omega="+str(-omega)+data_ext)
        sp2_m_re.plot(Npos_contours=10, spart=qr.part_ABS,
                      label="Rephasing\n $\omega="+str(-omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1],
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)],
                      show_diagonal="-k")   
        sp2_m_re.savefig(fftf_4)
        print("... saved into: ", fftf_4)
        fftf_5 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=NONR"+"_omega="+str(-omega)+data_ext)
        sp2_m_nr.plot(Npos_contours=10, spart=qr.part_ABS,
                      label="Non-rephasing\n $\omega="+str(-omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1],
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)],
                      show_diagonal="-k")      
        sp2_m_nr.savefig(fftf_5)
        print("... saved into: ", fftf_5)
        fftf_6 = os.path.join("sim_"+vib_loc, "twod_fft"+data_descr+
                               "_stype=tot"+"_omega="+str(-omega)+data_ext)
        sp2_m_to.plot(Npos_contours=10, spart=qr.part_ABS,
                      label="Total\n $\omega="+str(-omega)+
                      "$ cm$^{-1}$", text_loc=[0.05,0.1],
                      show_states=[Ep_l, Ep_u, Ep_u+numpy.abs(omega)],
                      show_diagonal="-k")      
        sp2_m_to.savefig(fftf_6)
        print("... saved into: ", fftf_6)

        if show_plots:
            #
            # Point evolutions at the expected peak positions
            #
            for ii in range(4):        
                points = fcont_p_re.get_point_evolution(Ep[ii,0], Ep[ii,1],
                                                        fcont_m_re.axis)
                points.apply_to_data(numpy.abs)
                if ii >= 3:
                    points.plot(show=True)
                else:
                    points.plot(show=False)
                    
            #points.apply_to_data(numpy.abs)
            #points.plot()

    
    # saving containers
#    fname = os.path.join("sim_"+vib_loc,"fcont_re"+data_descr+obj_ext)
#    print("Saving container into: "+fname)
#    fcont_p_re.save(fname)
#    fname = os.path.join("sim_"+vib_loc,"fcont_nr"+data_descr+obj_ext)
#    print("Saving container into: "+fname)
#    fcont_p_nr.save(fname)
#    fname = os.path.join("sim_"+vib_loc,"fcont_to"+data_descr+obj_ext)
#    print("Saving container into: "+fname)
#    fcont_p_to.save(fname)    
    fname = os.path.join("sim_"+vib_loc,"cont_p"+data_descr+obj_ext)
    print("Saving container into: "+fname)
    cont_p.save(fname)
    fname = os.path.join("sim_"+vib_loc,"cont_m"+data_descr+obj_ext)
    print("Saving container into: "+fname)
    cont_m.save(fname)
        
    return (sp1_p_re, sp1_p_nr, sp2_m_re, sp2_m_nr)
예제 #18
0
with qr.energy_units("1/cm"):
    agg.set_resonance_coupling_matrix(J_Matrix[0:3,0:3])

#agg.save("RC_Model_40_4_adjusted_CT_no_environment_unbuilt.hdf5")
qr.save_parcel(agg, os.path.join(pre_out,
                                 "RC_Model_40_4_adjusted_CT_no_environment_unbuilt.qrp"))


# In[3]:


# check that units were set correctly
rc = agg.resonance_coupling[1,0]
with qr.energy_units("1/cm"):
    print(qr.convert(rc, "int"))

with qr.energy_units("1/cm"):
    print(agg.get_resonance_coupling(1,0))


# In[4]:


# Bath correlation function
time = qr.TimeAxis(0.0, 1000, 1.0)

cfA_params = dict(ftype="OverdampedBrownian",
                  reorg=190, cortime=80, T=77, matsubara=100)
cfH_params = dict(ftype="OverdampedBrownian",
                  reorg=200, cortime=100, T=77, matsubara=100)
예제 #19
0
#
# Set the correlation function to the transitions on the molecules
#
m1.set_transition_environment((0, 1), cf)
m2.set_transition_environment((0, 1), cf)

#
# Build the aggregate
#
agg.build()

#
# Calculate absorption spectrum
#
asc = qr.AbsSpectrumCalculator(time, system=agg)
asc.bootstrap(rwa=qr.convert(10050, "1/cm", "int"), lab=lab)
abs1 = asc.calculate(raw=False)
abs1.normalize2()

#
# Plot the absorption spectrum
#
with qr.energy_units("1/cm"):
    abs1.plot(axis=[9000, 12000, 0.0, 1.01], color="b", show=False)

###############################################################################
#
# Calculation using effective Gaussian lineshape
#
###############################################################################

import quantarhei as qr

qr.Manager().gen_conf.legacy_relaxation = True

print("Preparing a model system:")

with qr.energy_units("1/cm"):
    mol1 = qr.Molecule([0.0, 12000])
    mol2 = qr.Molecule([0.0, 12000])
    mol3 = qr.Molecule([0.0, 12100])
    mol4 = qr.Molecule([0.0, 12100])

agg = qr.Aggregate([mol1, mol2, mol3, mol4])
agg.set_resonance_coupling(2,3,qr.convert(100.0,"1/cm","int"))
agg.set_resonance_coupling(1,3,qr.convert(100.0,"1/cm","int"))

with tempfile.TemporaryDirectory() as tdir:
    path = os.path.join(tdir,"agg.qrp")
    qr.save_parcel(agg,path)
    agg2 = qr.load_parcel(path)
agg2.build()

H = agg2.get_Hamiltonian()


print("...done")

print("Setting up Lindblad form relaxation:")
Ndim = 5
예제 #21
0
파일: twod.py 프로젝트: foxfoxfox7/mySci
with qr.energy_units('1/cm'):
    sd_low_freq = qr.SpectralDensity(t_ax_sd, params)

# Adding the high freq modes
sd_high_freq = db.get_SpectralDensity(t_ax_sd, "Wendling_JPCB_104_2000_5825")
ax = sd_low_freq.axis
sd_high_freq.axis = ax
sd_tot = sd_low_freq + sd_high_freq

cf = sd_tot.get_CorrelationFunction(temperature=temperature, ta=t_ax_sd)
# Assigning the correlation function to the list of molecules
for mol in for_agg:
    mol.set_transition_environment((0, 1), cf)

if _test_:
    reorg = qr.convert(sd_low_freq.get_reorganization_energy(), "int", "1/cm")
    print("input_reorg - ", reorg)

    with qr.energy_units("1/cm"):
        sd_tot.plot(show=True, axis=[0, 2000, 0.0, np.max(sd_tot.data)])
    cf.plot(show=True)

#######################################################################
# Dynamics
#######################################################################

# Test the setup by calculating the dynamics at same and diff energies
if _test_:
    energies1 = [energy] * num_mol
    energies2 = [energy - (100 * num_mol / 2)\
     + i * 100 for i in range(num_mol)]
예제 #22
0
            print("Fitted population decay time (exciton basis): ",
                  1.0 / popt_p_e[1])
            print("Fitted population decay time (site basis): ",
                  1.0 / popt_p_s[1])
        else:
            popt_p_e = [0.0, 10000.0]
            popt_p_s = [0.0, 10000.0]

        if J == 0.0:
            rat = 0.0
            balance = 0.0
        else:
            rat = popt_p_e[1]
            kBT = qr.core.units.kB_int * Temperature
            print("kBT = ", qr.convert(kBT, "int", "1/cm"), "cm^-1")
            with qr.eigenbasis_of(ham):
                balance = rat * numpy.exp(
                    -(ham.data[2, 2] - ham.data[1, 1]) / kBT)
            print("Uphill decay time from canonical detailed balance: ",
                  1.0 / balance)

            rate_predicted = 0.5 * balance + 0.5 * rat
            print(
                "Prediction for the decoherence time" +
                " based on population transfer:", 1.0 / rate_predicted)

        #
        # Exponential fitting of opt_coh and ext_coh
        #
#
# Integration over disorder
#
for e1 in es1:
    for e2 in es2:
        
        e_shift = e1 - Ecalc
        DE = e2 - e1
        
        # get the spectrum with DE and shift it by e_shift
        (N_DE, err) = des.locate(DE)
        #print(DE, N_DE, weight(e1, E1, width_dis[0])*
        #                weight(e2, E2, width_dis[1]))
        twod_a = spects[N_DE].deepcopy()
        twod_a.shift_energy(qr.convert(e_shift,"1/cm","int"))
        
        data[:,:] += weight(e1, E1, width_dis[0])* \
                     weight(e2, E2, width_dis[1])*twod_a.data[:,:]
        
        
twod_a.data[:,:] = data[:,:]/(N1_1*N1_2)

with qr.energy_units("1/cm"):
    twod_a.plot(spart=qr.part_ABS)
    if INP.save_fig:
        twod_a.savefig(INP.fig_file)

if INP.save_spectrum:
    twod_a.save(INP.spectrum_file)
예제 #24
0
# set bath correlation functions to the molecules
for i_m in range(N_molecules):
    mols[i_m].set_transition_environment((0, 1), cf)
    
# aggregate of molecules
agg = qr.Aggregate(mols)

agg.set_coupling_by_dipole_dipole()

# Building the aggregate
qr.log_report("Building aggregate")
agg.build()
qr.log_report("...done")

qr.log_detail("Resonance coupling matrix: ")
qr.log_detail(qr.convert(agg.resonance_coupling, "int", "1/cm"),
             use_indent=False)

# Dimension of the problem
HH = agg.get_Hamiltonian()
Nr = HH.dim
qr.log_detail("Hamiltonian has a rank:", Nr)

benchmark_report["Dimension"] = Nr
    
qr.log_report("Calculating Relaxation tensor:")
t1 = time.time()
(RT, ham) = agg.get_RelaxationTensor(timea, 
                                     relaxation_theory="standard_Redfield",
                                     as_operators=True)
t2 = time.time()
    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)
예제 #26
0
eUt = qr.qm.EvolutionSuperOperator(time2,
                                   HH,
                                   relt=LF,
                                   pdeph=p_deph,
                                   mode="all")
eUt.set_dense_dt(fine_splitting)

#
# We calculate evolution superoperator
#
eUt.calculate(show_progress=False)

olow_cm = omega - 10.0 / 2.0
ohigh_cm = omega + 10.0 / 2.0
olow = qr.convert(olow_cm, "1/cm", "int")
ohigh = qr.convert(ohigh_cm, "1/cm", "int")

print("---")
print("Calculating 2D spectra")
for t2 in time2.data:

    # this could save some memory of pathways become too big
    pways = dict()

    print("T2 =", t2, "fs (of T2_max =", time2.max, "fs)")

    twod = msc.calculate_one_system(t2,
                                    agg,
                                    eUt,
                                    lab,
예제 #27
0
# set bath correlation functions to the molecules
for i_m in range(N_molecules):
    mols[i_m].set_transition_environment((0, 1), cf)

# aggregate of molecules
agg = qr.Aggregate(mols)

agg.set_coupling_by_dipole_dipole()

# Building the aggregate
qr.log_report("Building aggregate")
agg.build()
qr.log_report("...done")

qr.log_detail("Resonance coupling matrix: ")
qr.log_detail(qr.convert(agg.resonance_coupling, "int", "1/cm"),
              use_indent=False)

# Dimension of the problem
HH = agg.get_Hamiltonian()
Nr = HH.dim
qr.log_detail("Hamiltonian has a rank:", Nr)

benchmark_report["Dimension"] = Nr

qr.log_report("Calculating Relaxation tensor:")
t1 = time.time()
(RT, ham) = agg.get_RelaxationTensor(timea,
                                     relaxation_theory="standard_Redfield",
                                     as_operators=True)
t2 = time.time()
예제 #28
0
Np = 13

ex2Dfile = "test.png"
plot_window = [11000, 13500, 11000, 13500]

t1axis = qr.TimeAxis(0.0, 1000, 1.0)
t2axis = qr.TimeAxis(0.0, 100, 10.0)
t3axis = qr.TimeAxis(0.0, 1000, 1.0)


pws = qr.load_parcel(os.path.join(pre_in,filename))

print(len(pws))

mscal = qr.MockTwoDSpectrumCalculator(t1axis, t2axis, t3axis)
mscal.bootstrap(rwa=qr.convert(12200,"1/cm","int"))

pw = pws[Np]
mscal.set_pathways([pw])

twod = mscal.calculate()

eUt = qr.load_parcel(os.path.join(pre_in,"eUt.qrp"))
oset = qr.load_parcel(os.path.join(dirn,"A_saved_state.qrp"))

with qr.energy_units("1/cm"):
    print(pw)
    twod.plot(window=plot_window, Npos_contours=10,              
              stype="total", spart="real")
    plt.show()
    
예제 #29
0
def run(omega,
        HR,
        dE,
        JJ,
        rate,
        E0,
        vib_loc="up",
        use_vib=True,
        stype=qr.signal_REPH,
        make_movie=False,
        save_eUt=False,
        t2_save_pathways=[],
        dname=None,
        trimer=None,
        disE=None):
    """Runs a complete set of simulations for a single set of parameters


    If disE is not None it tries to run averaging over Gaussian energetic
    disorder.

    """
    if dname is None:
        dname = "sim_" + vib_loc

    use_trimer = trimer["useit"]

    rate_sp = trimer["rate"]

    #
    #  PARAMETERS FROM INPUT FILE
    #
    dip1 = INP.dip1  # [1.5, 0.0, 0.0]
    dip2 = INP.dip2  # [-1.0, -1.0, 0.0]
    width = INP.feature_width  # 100.0
    width2 = INP.feature_width2

    normalize_maps_to_maximu = False
    trim_maps = False

    units = "1/cm"
    with qr.energy_units(units):

        data_descr = "_dO=" + str(dE) + "_omega=" + str(omega) + "_HR=" + str(
            HR) + "_J=" + str(JJ)

        if use_vib:
            sys_char = "_vib"
        else:
            sys_char = "_ele"
        data_ext = sys_char + ".png"
        obj_ext = sys_char + ".qrp"

    # parameters of the SP
    if use_trimer:
        E2 = trimer["E2"]
        epsa = (E0 + E2) / 2.0
        DE = trimer["DE"]
        J2 = 0.5 * numpy.sqrt(((E0 - E2)**2) - (DE**2))
        ESP2 = epsa + DE / 2.0
        ESP1 = epsa - DE / 2.0

    #
    #   Model system is a dimer of molecules
    #
    with qr.energy_units("1/cm"):

        if not use_trimer:

            mol1 = qr.Molecule([0.0, E0])
            mol2 = qr.Molecule([0.0, E0 + dE])

            print("Monomer 1 energy:", E0)
            print("Monomer 2 energy:", E0 + dE)

        else:

            if disE is not None:
                mol1 = qr.Molecule([0.0, ESP2 + disE[0]])
                mol2 = qr.Molecule([0.0, E0 + dE + disE[1]])
                print("Monomer 1 (SP_high) energy:", ESP2 + disE[0])
                print("Monomer 2 (B) energy:", E0 + dE + disE[1])
            else:
                mol1 = qr.Molecule([0.0, ESP2])
                mol2 = qr.Molecule([0.0, E0 + dE])
                print("Monomer 1 (SP_high) energy:", ESP2)
                print("Monomer 2 (B) energy:", E0 + dE)
            if disE is not None:
                mol3 = qr.Molecule([0.0, ESP1 + disE[2]])
                print("Monomer 3 (SP_low) energy:", ESP1 + disE[2])
            else:
                mol3 = qr.Molecule([0.0, ESP1])
                print("Monomer 3 (SP_low) energy:", ESP1)
            mol3.set_transition_width((0, 1), width2)
            mol3.set_dipole(0, 1, trimer["dipsp"])

        mol1.set_transition_width((0, 1), width2)
        mol1.set_dipole(0, 1, dip1)

        mol2.set_transition_width((0, 1), width)
        mol2.set_dipole(0, 1, dip2)

    if use_trimer:
        agg = qr.Aggregate([mol1, mol2, mol3])
    else:
        agg = qr.Aggregate([mol1, mol2])

    if use_trimer:

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling(0, 1, JJ)
            print("B - SP_high coupling:", JJ)
            agg.set_resonance_coupling(0, 2, J2)
            print("SP coupling:", J2)

    else:

        with qr.energy_units("1/cm"):
            agg.set_resonance_coupling(0, 1, JJ)

    #
    # Electronic only aggregate
    #
    agg_el = agg.deepcopy()

    #
    # if nuclear vibrations are to be added, do it here
    #
    if use_vib:

        with qr.energy_units("1/cm"):
            mod1 = qr.Mode(omega)
            mod2 = qr.Mode(omega)

        if vib_loc == "down":
            set_vib = [True, False]
        elif vib_loc == "up":
            set_vib = [False, True]
        elif vib_loc == "both":
            set_vib = [True, True]
        else:
            raise Exception("Unknown location of the vibrations")

        if set_vib[0]:
            print("Vibrations set for SP_high molecule")
            mol1.add_Mode(mod1)
            mod1.set_nmax(0, INP.no_g_vib)
            mod1.set_nmax(1, INP.no_e_vib)
            mod1.set_HR(1, HR)

        if set_vib[1]:
            print("Vibrations set for B molecule")
            mol2.add_Mode(mod2)
            mod2.set_nmax(0, INP.no_g_vib)
            mod2.set_nmax(1, INP.no_e_vib)
            mod2.set_HR(1, HR)

    agg3 = agg.deepcopy()

    agg.build(mult=1)
    agg_el.build(mult=1)

    HH = agg.get_Hamiltonian()
    He = agg_el.get_Hamiltonian()

    #
    # Laboratory setup
    #
    lab = qr.LabSetup()
    lab.set_polarizations(pulse_polarizations=[X, X, X],
                          detection_polarization=X)

    t2_N_steps = INP.t2_N_steps
    t2_time_step = INP.t2_time_step
    time2 = qr.TimeAxis(0.0, t2_N_steps, t2_time_step)

    cont_p = qr.TwoDResponseContainer(t2axis=time2)
    cont_m = qr.TwoDResponseContainer(t2axis=time2)
    #
    # spectra will be indexed by the times in the time axis `time2`
    #
    cont_p.use_indexing_type(time2)

    #
    # We define two-time axes, which will be FFTed and will define
    # the omega_1 and omega_3 axes of the 2D spectrum
    #
    t1_N_steps = INP.t1_N_steps
    t1_time_step = INP.t1_time_step
    t3_N_steps = INP.t3_N_steps
    t3_time_step = INP.t3_time_step
    t1axis = qr.TimeAxis(0.0, t1_N_steps, t1_time_step)
    t3axis = qr.TimeAxis(0.0, t3_N_steps, t3_time_step)

    #
    # This calculator calculated 2D spectra from the effective width
    #
    msc = qr.MockTwoDResponseCalculator(t1axis, time2, t3axis)
    with qr.energy_units("1/cm"):
        msc.bootstrap(rwa=E0, shape="Gaussian")

    #
    # System-bath interaction including vibrational states
    #
    operators = []
    rates = []

    if use_trimer:

        print("Relaxation rates: ", rate, rate_sp)

        with qr.eigenbasis_of(He):
            if He.data[3, 3] < He.data[2, 2]:
                Exception("Electronic states not orderred!")
            operators.append(qr.qm.ProjectionOperator(2, 3, dim=He.dim))
            with qr.energy_units("1/cm"):
                print("2<-3", He.data[2, 2], He.data[3, 3])
            rates.append(rate)
            print("Transfer time B -> SP:", 1.0 / rate)
            if He.data[2, 2] < He.data[1, 1]:
                Exception("Electronic states not orderred!")
            operators.append(qr.qm.ProjectionOperator(1, 2, dim=He.dim))
            with qr.energy_units("1/cm"):
                print("1<-2", He.data[1, 1], He.data[2, 2])
            rates.append(rate_sp)
            print("Transfer time P+ -> P-:", 1.0 / rate_sp)

        # include detailed balace
        if detailed_balance:
            with qr.eigenbasis_of(He):
                T = INP.temperature  #77.0
                Den = (He.data[3, 3] - He.data[2, 2]) / (kB_int * T)
                operators.append(qr.qm.ProjectionOperator(3, 2, dim=He.dim))
                thermal_fac = numpy.exp(-Den)
            rates.append(rate * thermal_fac)
        else:
            with qr.eigenbasis_of(He):
                if He.data[2, 2] < He.data[1, 1]:
                    Exception("Electronic states not orderred!")
                operators.append(qr.qm.ProjectionOperator(1, 2, dim=He.dim))
            rates.append(rate)

        # include detailed balace
        if detailed_balance:
            with qr.eigenbasis_of(He):
                T = INP.temperature  #77.0
                Den = (He.data[2, 2] - He.data[1, 1]) / (kB_int * T)
                operators.append(qr.qm.ProjectionOperator(2, 1, dim=He.dim))
                thermal_fac = numpy.exp(-Den)
            rates.append(rate * thermal_fac)

    sbi = qr.qm.SystemBathInteraction(sys_operators=operators, rates=rates)
    sbi.set_system(agg)

    #
    # Liouville form for relaxation
    #
    LF = qr.qm.ElectronicLindbladForm(HH, sbi, as_operators=True)

    #
    # Pure dephasing
    #
    p_deph = qr.qm.ElectronicPureDephasing(agg, dtype="Gaussian")

    # we simplify calculations by converting dephasing to
    # corresponding Lorentzian form
    p_deph.convert_to("Lorentzian")

    eUt = qr.qm.EvolutionSuperOperator(time2,
                                       HH,
                                       relt=LF,
                                       pdeph=p_deph,
                                       mode="all")
    eUt.set_dense_dt(INP.fine_splitting)

    #
    # We calculate evolution superoperator
    #
    eUt.calculate(show_progress=False)

    # save the evolution operator
    if save_eUt:
        eut_name = os.path.join(
            dname, "eUt" + "_omega2=" + str(omega) + data_descr + obj_ext)
        eUt.save(eut_name)

    #
    # Prepare aggregate with all states (including 2-EX band)
    #
    agg3.build(mult=2)
    agg3.diagonalize()

    pways = dict()

    olow_cm = omega - INP.omega_uncertainty / 2.0
    ohigh_cm = omega + INP.omega_uncertainty / 2.0
    olow = qr.convert(olow_cm, "1/cm", "int")
    ohigh = qr.convert(ohigh_cm, "1/cm", "int")

    for t2 in time2.data:

        # this could save some memory of pathways become too big
        pways = dict()

        print("T2 =", t2)

        twod = msc.calculate_one_system(t2,
                                        agg3,
                                        eUt,
                                        lab,
                                        pways=pways,
                                        dtol=1.0e-12,
                                        selection=[["omega2", [olow, ohigh]]])
        pws = pways[str(t2)]
        npa = len(pws)
        print(" p:", npa)
        has_R = False
        has_NR = False
        for pw in pws:
            if pw.pathway_type == "NR":
                has_NR = True
            elif pw.pathway_type == "R":
                has_R = True

        print(" R:", has_R, ", NR:", has_NR)

        if t2 in t2_save_pathways:
            pws_name = os.path.join(
                dname, "pws_t2=" + str(t2) + "_omega2=" + str(omega) +
                data_descr + obj_ext)
            qr.save_parcel(pways[str(t2)], pws_name)

        cont_p.set_spectrum(twod)

        twod = msc.calculate_one_system(t2,
                                        agg3,
                                        eUt,
                                        lab,
                                        pways=pways,
                                        dtol=1.0e-12,
                                        selection=[["omega2", [-ohigh,
                                                               -olow]]])

        pws = pways[str(t2)]
        npa = len(pws)
        print(" m:", npa)
        has_R = False
        has_NR = False
        for pw in pws:
            if pw.pathway_type == "NR":
                has_NR = True
            elif pw.pathway_type == "R":
                has_R = True

        print(" R:", has_R, ", NR:", has_NR)

        if t2 in t2_save_pathways:
            pws_name = os.path.join(
                dname, "pws_t2=" + str(t2) + "_omega2=" + str(-omega) +
                data_descr + obj_ext)
            qr.save_parcel(pways[str(t2)], pws_name)

        cont_m.set_spectrum(twod)

    if make_movie:
        with qr.energy_units("1/cm"):
            cont_p.make_movie("mov.mp4")

    #
    # Save aggregate when a single calculation is done
    #
    if save_eUt:
        fname = os.path.join(dname, "aggregate.qrp")
        agg3.save(fname)

    #
    # Window function for subsequenty FFT
    #
    window = func.Tukey(time2, r=INP.tukey_window_r, sym=False)

    #
    # FFT with the window function
    #
    # Specify REPH, NONR or `total` to get different types of spectra
    #
    print("Calculating FFT of the 2D maps")
    #fcont = cont.fft(window=window, dtype=stype) #, dpart="real", offset=0.0)

    fcont_p_re = cont_p.fft(window=window, dtype=qr.signal_REPH)
    fcont_p_nr = cont_p.fft(window=window, dtype=qr.signal_NONR)
    fcont_p_to = cont_p.fft(window=window, dtype=qr.signal_TOTL)

    if normalize_maps_to_maximu:
        fcont_p_re.normalize2(dpart=qr.part_ABS)
        fcont_p_nr.normalize2(dpart=qr.part_ABS)
        fcont_p_to.normalize2(dpart=qr.part_ABS)

    fcont_m_re = cont_m.fft(window=window, dtype=qr.signal_REPH)
    fcont_m_nr = cont_m.fft(window=window, dtype=qr.signal_NONR)
    fcont_m_to = cont_m.fft(window=window, dtype=qr.signal_TOTL)

    if normalize_maps_to_maximu:
        fcont_m_re.normalize2(dpart=qr.part_ABS)
        fcont_m_nr.normalize2(dpart=qr.part_ABS)
        fcont_m_to.normalize2(dpart=qr.part_ABS)

    if trim_maps:
        twin = INP.trim_maps_to
        with qr.energy_units("1/cm"):
            fcont_p_re.trimall_to(window=twin)
            fcont_p_nr.trimall_to(window=twin)
            fcont_p_to.trimall_to(window=twin)

    show_omega = omega

    with qr.frequency_units("1/cm"):
        sp1_p_re, show_Npoint1 = fcont_p_re.get_nearest(show_omega)
        sp2_p_re, show_Npoint2 = fcont_p_re.get_nearest(-show_omega)
        sp1_p_nr, show_Npoint1 = fcont_p_nr.get_nearest(show_omega)
        sp2_p_nr, show_Npoint2 = fcont_p_nr.get_nearest(-show_omega)
        sp1_p_to, show_Npoint1 = fcont_p_to.get_nearest(show_omega)
        sp2_p_to, show_Npoint2 = fcont_p_to.get_nearest(-show_omega)
        sp1_m_re, show_Npoint1 = fcont_m_re.get_nearest(show_omega)
        sp2_m_re, show_Npoint2 = fcont_m_re.get_nearest(-show_omega)
        sp1_m_nr, show_Npoint1 = fcont_m_nr.get_nearest(show_omega)
        sp2_m_nr, show_Npoint2 = fcont_m_nr.get_nearest(-show_omega)
        sp1_m_to, show_Npoint1 = fcont_m_to.get_nearest(show_omega)
        sp2_m_to, show_Npoint2 = fcont_m_to.get_nearest(-show_omega)

    with qr.energy_units(units):

        if show_plots:

            #
            # Spots to look at in detail
            #
            with qr.energy_units("1/cm"):
                with qr.eigenbasis_of(He):
                    Ep_l = He.data[1, 1]
                    Ep_u = He.data[2, 2]

            Ep = numpy.zeros((4, 2))
            Ep[0, 0] = Ep_l
            Ep[0, 1] = Ep_l
            Ep[1, 0] = Ep_l
            Ep[1, 1] = Ep_u
            Ep[2, 0] = Ep_u
            Ep[2, 1] = Ep_l
            Ep[3, 0] = Ep_u
            Ep[3, 1] = Ep_u

            print("\nPlotting and saving spectrum at frequency:",
                  fcont_p_re.axis.data[show_Npoint1], units)

            fftf_1 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=REPH" + "_omega=" +
                str(omega) + data_ext)
            sp1_p_re.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Rephasing\n $\omega=" + str(omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp1_p_re.savefig(fftf_1)
            print("... saved into: ", fftf_1)
            fftf_2 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=NONR" + "_omega=" +
                str(omega) + data_ext)
            sp1_p_nr.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Non-rephasing\n $\omega=" + str(omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp1_p_nr.savefig(fftf_2)
            print("... saved into: ", fftf_2)
            fftf_3 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=tot" + "_omega=" +
                str(omega) + data_ext)
            sp1_p_to.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Total\n $\omega=" + str(omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp1_p_to.savefig(fftf_3)
            print("... saved into: ", fftf_3)

            #
            # Point evolutions at the expected peak positions
            #

            for ii in range(4):
                points = fcont_p_re.get_point_evolution(
                    Ep[ii, 0], Ep[ii, 1], fcont_p_re.axis)
                points.apply_to_data(numpy.abs)
                if ii >= 3:
                    points.plot(show=True)
                else:
                    points.plot(show=False)

            print("\nPlotting and saving spectrum at frequency:",
                  fcont_m_re.axis.data[show_Npoint2], units)
            fftf_4 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=REPH" + "_omega=" +
                str(-omega) + data_ext)
            sp2_m_re.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Rephasing\n $\omega=" + str(-omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp2_m_re.savefig(fftf_4)
            print("... saved into: ", fftf_4)
            fftf_5 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=NONR" + "_omega=" +
                str(-omega) + data_ext)
            sp2_m_nr.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Non-rephasing\n $\omega=" + str(-omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp2_m_nr.savefig(fftf_5)
            print("... saved into: ", fftf_5)
            fftf_6 = os.path.join(
                dname, "twod_fft" + data_descr + "_stype=tot" + "_omega=" +
                str(-omega) + data_ext)
            sp2_m_to.plot(Npos_contours=10,
                          spart=qr.part_ABS,
                          label="Total\n $\omega=" + str(-omega) +
                          "$ cm$^{-1}$",
                          text_loc=[0.05, 0.1],
                          show_states=[Ep_l, Ep_u, Ep_u + numpy.abs(omega)],
                          show_diagonal="-k")
            sp2_m_to.savefig(fftf_6)
            print("... saved into: ", fftf_6)

            #
            # Point evolutions at the expected peak positions
            #
            for ii in range(4):
                points = fcont_p_re.get_point_evolution(
                    Ep[ii, 0], Ep[ii, 1], fcont_m_re.axis)
                points.apply_to_data(numpy.abs)
                if ii >= 3:
                    points.plot(show=True)
                else:
                    points.plot(show=False)

    save_containers = False

    if save_containers:
        fname = os.path.join(dname, "cont_p" + data_descr + obj_ext)
        print("Saving container into: " + fname)
        cont_p.save(fname)
        fname = os.path.join(dname, "cont_m" + data_descr + obj_ext)
        print("Saving container into: " + fname)
        cont_m.save(fname)

    import resource
    memo = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / (1024 * 1024)
    print("Memory usage: ", memo, "in MB")

    return (sp1_p_re, sp1_p_nr, sp2_m_re, sp2_m_nr)
예제 #30
0
            
            print("Fitted population decay time (exciton basis): ",
                  1.0/popt_p_e[1])
            print("Fitted population decay time (site basis): ",
                  1.0/popt_p_s[1])
        else:
            popt_p_e = [0.0, 10000.0]
            popt_p_s = [0.0, 10000.0]
            
        if J == 0.0:
            rat = 0.0
            balance = 0.0
        else:
            rat = popt_p_e[1]
            kBT = qr.core.units.kB_int*Temperature
            print("kBT = ", qr.convert(kBT,"int","1/cm"),"cm^-1")
            with qr.eigenbasis_of(ham):
                balance = rat*numpy.exp(-(ham.data[2,2]-ham.data[1,1])/kBT)
            print("Uphill decay time from canonical detailed balance: ",
                  1.0/balance)
        
            rate_predicted = 0.5*balance + 0.5*rat
            print("Prediction for the decoherence time"+
                  " based on population transfer:", 1.0/rate_predicted)
    

        #
        # Exponential fitting of opt_coh and ext_coh
        #
        
        # Define Quantarhei DFunction which can fit itself
예제 #31
0
# Create an aggregate
#
agg = qr.Aggregate(molecules=[mol])

agg.build()

#
# Time axes and the calculator
#
t1axis = qr.TimeAxis(0.0, 1000, 10.0)
t3axis = qr.TimeAxis(0.0, 1000, 10.0)
t2axis = qr.TimeAxis(0.0, Nt2, dt2)

# FIXME: TwoDResponseCalculator
msc = qr.MockTwoDResponseCalculator(t1axis, t2axis, t3axis)
msc.bootstrap(rwa=qr.convert(E1, "1/cm", "int"), shape="Gaussian")

#
# Laboratory setup
#

lab = LabSetup()
lab.set_polarizations(pulse_polarizations=[X, X, X], detection_polarization=X)

#
# Hamiltonian is required
#
H = agg.get_Hamiltonian()

#
# Evolution superoperator
예제 #32
0
# Aggregate with vibrational states, Hamiltonian generated up to single
# exciton states in a Two-particle approximation
# This object is used for calculation of dynamics
#
agg.build(mult=1, vibgen_approx="TPA")

#
# agg2 object will be used for calculation of 2D spectra
# so it needs to know how to represent the spectra (what width it should have).
# It also has to be built with
# two-exciton states (in two-particle approximation)
#

for mol_name in transition_widths:

    width = qr.convert(transition_widths[mol_name], "1/cm", "int")
    mol = agg2.get_Molecule_by_name(mol_name)
    mol.set_transition_width((0, 1), width)

print("Aggregate has ", agg2.nmono, "single excited electronic states")

agg2.build(mult=2, vibgen_approx="TPA")

print("and ", agg2.Ntot, " (electro-vibrational) states in total")
print("Number of single exciton states :", agg2.Nb[0] + agg2.Nb[1])

qr.save_parcel(agg2, os.path.join(pre_out, "agg2_built.qrp"))

#
# Electronic aggregate is built with single exciton states only
#
예제 #33
0
# This object is used for calculation of dynamics
#
agg.build(mult=1, vibgen_approx="TPA")

#
# width of the spectral features in 1/cm
#
wincm = 500

#
# agg2 object will be used for calculation of 2D spectra
# so it needs to know how to represent the spectra (what
# width it should have), and it has to be built with
# two-exciton states (in two-particle approximation)
#
width = qr.convert(wincm, "1/cm", "int")
PM = agg2.get_Molecule_by_name("PM")
PM.set_transition_width((0, 1), width)
PL = agg2.get_Molecule_by_name("PL")
PL.set_transition_width((0, 1), width)

width = qr.convert(wincm, "1/cm", "int")
BM = agg2.get_Molecule_by_name("BM")
BM.set_transition_width((0, 1), width)
BL = agg2.get_Molecule_by_name("BL")
BL.set_transition_width((0, 1), width)

width = qr.convert(wincm, "1/cm", "int")
PCT1 = agg2.get_Molecule_by_name("PCT1")
PCT1.set_transition_width((0, 1), width)
PCT2 = agg2.get_Molecule_by_name("PCT2")