time_propagator, t[-1], time_step, wave_nums=False) return dynamics[:, 0] print '[Calculating Forster rates...]' print 'Started at: ' + str(time_utils.getTime()) for i, v in enumerate(reorg_energy_values): #print 'Calculating rates for reorg energy: ' + str(v) forster_time = np.linspace(0, 20., 16000) lbf = os.site_lbf_ed(forster_time, os.lbf_coeffs(v, cutoff_freq, temperature, None, 5)) forster_rates[i] = os.forster_rate(100., 0, v, v, lbf, lbf, 0, 0, np.array([1., 0]), np.array([0, 1.]), system_hamiltonian, forster_time) print 'Finished at: ' + str(time_utils.getTime()) def calculate_HEOM(reorg_energy): print reorg_energy system_hamiltonian = np.array([[100., 20.], [20., 0]]) cutoff_freq = 53. temperature = 300. hs = HierarchySolver(system_hamiltonian, environment(reorg_energy, beta, K), beta, N=trunc_level) hs.init_system_dm = init_state HEOM_history, time = hs.calculate_time_evolution(time_step, duration)
bare_chl_energy = system_hamiltonian[4,4] - total_reorg_energy bare_phe_energy = system_hamiltonian[6,6] - total_reorg_energy bare_CT1_energy = average_site_CT_energies[6] - total_reorg_energy*CT1_scaling bare_CT2_energy = average_site_CT_energies[7] - total_reorg_energy*CT2_scaling chl_state = np.array([0, 0, 1., 0, 0, 0, 0, 0]) phe_state = np.array([0, 0, 0, 0, 1., 0, 0, 0]) CT1_state = np.array([0, 0, 0, 0, 0, 0, 1., 0]) CT2_state = np.array([0, 0, 0, 0, 0, 0, 0, 1.]) time = np.linspace(0,2.,256000) site_lbf = os.site_lbf_ed(time, os.lbf_coeffs(reorg_energy, cutoff_freq, temperature, None, 100)) # primary CT rates in site basis chl_CT1_rate = os.forster_rate(bare_chl_energy, bare_CT1_energy, reorg_energy, reorg_energy*CT1_scaling, \ site_lbf, site_lbf*CT1_scaling, 0, 0, chl_state, CT1_state, coherent_hamiltonian, time) CT1_chl_rate = os.forster_rate(bare_CT1_energy, bare_chl_energy, reorg_energy, reorg_energy*CT1_scaling, \ site_lbf, site_lbf*CT1_scaling, 0, 0, chl_state, CT1_state, coherent_hamiltonian, time) phe_CT1_rate = os.forster_rate(bare_phe_energy, bare_CT1_energy, reorg_energy, reorg_energy*CT1_scaling, \ site_lbf, site_lbf*CT1_scaling, 0, 0, phe_state, CT1_state, coherent_hamiltonian, time) CT1_phe_rate = os.forster_rate(bare_CT1_energy, bare_phe_energy, reorg_energy, reorg_energy*CT1_scaling, \ site_lbf, site_lbf*CT1_scaling, 0, 0, phe_state, CT1_state, coherent_hamiltonian, time) forward_exciton_CT_rates = [2.86359127e+00, 2.09614196e-02, 7.89708095e+01, 5.47195323e+00, 2.91393623e+00, 2.92997893e-01] backward_exciton_CT_rates = [2.32445332e+00, 1.40848357e-02, 4.18754762e+01, 2.46325661e+00, 1.25847348e+00, 3.69904601e-02] # secondary CT rates CT1_CT2_rate = os.forster_rate(bare_CT1_energy, bare_CT2_energy, reorg_energy*CT1_scaling, reorg_energy*CT2_scaling, \ site_lbf*CT1_scaling, site_lbf*CT2_scaling, 0, 0, CT1_state, CT2_state, coherent_hamiltonian, time) CT2_CT1_rate = os.forster_rate(bare_CT2_energy, bare_CT1_energy, reorg_energy*CT1_scaling, reorg_energy*CT2_scaling, \ site_lbf*CT1_scaling, site_lbf*CT2_scaling, 0, 0, CT1_state, CT2_state, coherent_hamiltonian, time)
init_state = np.array([[1., 0], [0, 0]]) hs = HierarchySolver(system_hamiltonian, 1., cutoff_freq, temperature) # error function for least squares fit def residuals(p, y, pops1, pops2): k12, k21 = p return y - (-k12*pops1 + k21*pops2) print '[Calculating Forster rates...]' print 'Started at: ' + str(time_utils.getTime()) for i,v in enumerate(reorg_energy_values): #print 'Calculating rates for reorg energy: ' + str(v) forster_time = np.linspace(0, 20., 16000) lbf = os.site_lbf_ed(forster_time, os.lbf_coeffs(v, cutoff_freq, temperature, None, 5)) forster_rates[i] = os.forster_rate(100., 0, v, v, lbf, lbf, 0, 0, np.array([1., 0]), np.array([0, 1.]), system_hamiltonian, forster_time) print 'Finished at: ' + str(time_utils.getTime()) def calculate_HEOM(reorg_energy): system_hamiltonian = np.array([[100., 20.], [20., 0]]) cutoff_freq = 53. temperature = 300. init_state = np.array([[1., 0], [0, 0]]) time_step = 0.00005 duration = 5. hs = HierarchySolver(system_hamiltonian, reorg_energy, cutoff_freq, temperature) HEOM_history, time = hs.hierarchy_time_evolution(init_state, 18, time_step, duration) return HEOM_history
# lbf = site_lbf[i] # break # return np.exp(1.j*(E1-E2)*t) * np.exp(-1.j*(E_reorg1+E_reorg2)*t) * np.exp(-lbf-lbf) # # print 2. * integrate.simps(np.real(np.array([integrand_func(t) for t in time]))) # # plt.plot(time, np.array([integrand_func(t) for t in time])) # plt.show() # try to reproduce dimer rates using code copied from Mathematica rates_data = [] time_interval = 20 time = np.linspace(0, time_interval, time_interval*16000) site_lbf = os.site_lbf_ed(time, os.lbf_coeffs(reorg_energy, cutoff_freq, temperature, None, 20)) for i,V in enumerate(coupling_values): rates = [] for delta_E in delta_E_values: H = hamiltonian(delta_E, V) rates.append(os.forster_rate(H[0,0], H[1,1], reorg_energy, reorg_energy, site_lbf, site_lbf, 0, 0, np.array([1.,0]), np.array([0,1.]), H, time)) rates_data.append(rates) for i,rates in enumerate(rates_data): plt.subplot(1,3,i+1) plt.loglog(delta_E_values, utils.WAVENUMS_TO_INVERSE_PS*np.array(rates)) plt.ylim(0.01, 200) plt.xlim(5,1000) plt.show()
primary_CT_scaling = 3. primary_CT_reorg_energy = primary_CT_scaling * total_site_reorg_energy primary_CT_state = np.array([0, 0, 0, 0, 0, 0, 1., 0]) secondary_CT_scaling = 4. secondary_CT_reorg_energy = secondary_CT_scaling * total_site_reorg_energy secondary_CT_state = np.array([0, 0, 0, 0, 0, 0, 0, 1.]) # calculate Forster rates to primary and secondary CT states forward_primary_forster_rates = np.zeros(site_hamiltonian.shape[0]) backward_primary_forster_rates = np.zeros(site_hamiltonian.shape[0]) for i,E in enumerate(evals): # double check the effect of the lifetimes on the Forster rates # also check Forster rates converge with the number of time points used forward_primary_forster_rates[i] = os.forster_rate(E, hamiltonian[6,6]-primary_CT_reorg_energy, exciton_reorg_energies[i], primary_CT_reorg_energy, \ exciton_lbfs[i], primary_CT_scaling*lbf, 0, 0, \ np.append(evecs[i], [0,0]), primary_CT_state, hamiltonian, time) backward_primary_forster_rates[i] = os.forster_rate(hamiltonian[6,6]-primary_CT_reorg_energy, E, exciton_reorg_energies[i], primary_CT_reorg_energy, \ exciton_lbfs[i], primary_CT_scaling*lbf, 0, 0, \ np.append(evecs[i], [0,0]), primary_CT_state, hamiltonian, time) # construct Liouvillian liouvillian = np.zeros(hamiltonian.shape) liouvillian[:6,:6] = MRT_rates liouvillian[6,:6] = forward_primary_forster_rates liouvillian.T[6,:6] = backward_primary_forster_rates # forward secondary CT rate liouvillian[7,6] = os.forster_rate(hamiltonian[6,6]-primary_CT_reorg_energy, hamiltonian[7,7]-secondary_CT_reorg_energy, \ primary_CT_reorg_energy, secondary_CT_reorg_energy, \ primary_CT_scaling*lbf, secondary_CT_scaling*lbf, 0, 0, \ primary_CT_state, secondary_CT_state, hamiltonian, time)