def step_given_7(context): """ Given I have a Hamiltonian H, Lidblad form L and initial density matrix R """ # create test aggregatedimer agg = qr.TestAggregate("trimer-2") agg.build() # get the associated time axis and the relaxation tensor and Hamiltonian time = qr.TimeAxis(0, 320, 1.0) time2 = qr.TimeAxis(0, 32, 10.0) context.time = time context.time2 = time2 HH = agg.get_Hamiltonian() context.H = HH SBI = qr.qm.TestSystemBathInteraction(name="trimer-2-lind") LL = qr.qm.LindbladForm(HH, SBI) context.L= LL # initial density matrix R = qr.ReducedDensityMatrix(dim=HH.dim) R.data[2,2] = 1.0 context.R = R
def step_when_2(context, time_step, N_dense): """ When I calculate EvolutionSuperOperator using only PureDephasing D with {time_step} and {N_dense} """ # get the associated time axis and the relaxation tensor and Hamiltonian dt = float(time_step) N_dense = int(N_dense) time = qr.TimeAxis(0, 1320, 1.0) time2 = qr.TimeAxis(0, 132, dt) context.time = time context.time2 = time2 HH = context.H DD = context.D print("Dephasing type: ", DD.dtype) # This tests if it is possible to ignore relaxation tensor in defining # evolution superoperator L = qr.qm.LindbladForm(HH, sbi=None) U = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD) U.set_dense_dt(N_dense) with qr.eigenbasis_of(HH): U.calculate() context.U = U
def test_TwoDResponseCalculator(self): """Testing basic functions of the TwoDSpectrumCalculator class """ t1 = qr.TimeAxis(0.0, 1000, 1.0) t3 = qr.TimeAxis(0.0, 1000, 1.0) t2 = qr.TimeAxis(30, 10, 10.0) twod_calc = qr.TwoDResponseCalculator(t1, t2, t3)
def step_when_2(context, N_dense): """ When I calculate evolution superoperator U with time step {N_dense} times large than needed for numerics """ # parameter from outside Nd = int(N_dense) # all that is needed from context HH = context.H LL = context.L time = context.time # time step and number of steps Nt = time.length dt = time.step # we will make Nd times longer steps Nt_u = int(Nt / Nd) dt_u = dt * Nd # new time axis time_u = qr.TimeAxis(0.0, Nt_u, dt_u) # calculate evolution superoperator U = qr.qm.EvolutionSuperOperator(time=time_u, ham=HH, relt=LL) U.set_dense_dt(Nd) U.calculate() # save into context context.U = U
def test_dynamics(self, en_method = None): # Adding the energies to the molecules. Neeed to be done before agg mol_list_temp = self._temp_assign_energies(method = en_method) aggregate = self._temp_build_agg(agg_list = mol_list_temp) # Propagation axis length t13_ax plus padding with intervals of 1 #t1_len = int(((t13_ax.length+padding-1)*t13_ax.step)+1) t2_prop_axis = qr.TimeAxis(0.0, 1000, 1) # Generates the propagator to describe motion in the aggregate prop_Redfield = aggregate.get_ReducedDensityMatrixPropagator( t2_prop_axis, relaxation_theory="stR", time_dependent=False, secular_relaxation=True ) # Obtaining the density matrix shp = aggregate.get_Hamiltonian().dim rho_i1 = qr.ReducedDensityMatrix(dim=shp, name="Initial DM") # Setting initial conditions rho_i1.data[shp-1,shp-1] = 1.0 # Propagating the system along the t13_ax_ax time axis rho_t1 = prop_Redfield.propagate(rho_i1, name="Redfield evo from agg") rho_t1.plot(coherences=False, axis=[0,t2_prop_axis.length,0,1.0], show=True)
def assign_spec_dens(self, sd_type = 'OverdampedBrownian', high_freq = True): t_ax_sd = qr.TimeAxis(0.0, 10000, 1) db = SpectralDensityDB() # Parameters for spectral density. ODBO, Renger or Silbey params = { "ftype": sd_type, "alternative_form": True, "reorg": self.reorg, "T": self.temp, "cortime": self.cor_time } with qr.energy_units('1/cm'): sd_low_freq = qr.SpectralDensity(t_ax_sd, params) if high_freq: # 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=self.temp, ta=t_ax_sd) # Assigning the correlation function to the list of molecules else: cf = sd_low_freq.get_CorrelationFunction(temperature=self.temp, ta=t_ax_sd) for mol in self.mol_list: mol.set_transition_environment((0,1),cf)
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)
def test_dynamics(agg_list, energies): # Adding the energies to the molecules. Neeed to be done before agg with qr.energy_units("1/cm"): for i, mol in enumerate(agg_list): mol.set_energy(1, energies[i]) # Creation of the aggregate for dynamics. multiplicity can be 1 agg = qr.Aggregate(molecules=agg_list) agg.set_coupling_by_dipole_dipole(epsr=1.21) agg.build(mult=1) agg.diagonalize() # Creating a propagation axis length t13_ax plus padding with intervals 1 t2_prop_axis = qr.TimeAxis(0.0, 1000, 1) # Generates the propagator to describe motion in the aggregate prop_Redfield = agg.get_ReducedDensityMatrixPropagator( t2_prop_axis, relaxation_theory="stR", time_dependent=False, secular_relaxation=True ) # Obtaining the density matrix shp = agg.get_Hamiltonian().dim rho_i1 = qr.ReducedDensityMatrix(dim=shp, name="Initial DM") # Setting initial conditions rho_i1.data[shp-1,shp-1] = 1.0 # Propagating the system along the t13_ax_ax time axis rho_t1 = prop_Redfield.propagate(rho_i1, name="Redfield evo from agg") rho_t1.plot(coherences=False, axis=[0,t2_prop_axis.length,0,1.0], show=True)
def get_resp_object(respR, respN, time_ax, rwa, time_t2): onetwod = qr.TwoDResponse() tstart = int(time_ax[0]) tlen = int(len(time_ax)) tstep = int(time_ax[1]-time_ax[0]) t13 = qr.TimeAxis(tstart, tlen, tstep) t13.atype = 'complete' oa13 = t13.get_FrequencyAxis() oa13.data += rwa oa13.start += rwa onetwod.set_axis_1(oa13) onetwod.set_axis_3(oa13) ftresp = np.fft.fft(respR,axis=1) ftresp = np.fft.ifft(ftresp,axis=0) reph2D = np.fft.fftshift(ftresp) ftresp = np.fft.ifft(respN,axis=1) ftresp = np.fft.ifft(ftresp,axis=0)*ftresp.shape[1] nonr2D = np.fft.fftshift(ftresp) onetwod.set_resolution("signals") onetwod._add_data(reph2D, dtype=qr.signal_REPH) onetwod._add_data(nonr2D, dtype=qr.signal_NONR) onetwod.set_t2(time_t2) return onetwod
def load_resp_dict(file_path, las_pol, signal_names, test_pad): resp_containers_part = [] with open(file_path + '.pkl', 'rb') as f: resp_dict = pickle.load(f) t2start = int(resp_dict['t2axis'][0]) t2len = int(len(resp_dict['t2axis'])) t2step = int(resp_dict['t2axis'][1]) t2_dict = qr.TimeAxis(t2start, t2len, t2step) t13start = resp_dict['time'][0] t13step = resp_dict['time'][1] t13end = resp_dict['time'][-1] + 1 + (t13step * test_pad) t13_fr = np.arange(t13start, t13end, t13step) t13_fr_len = len(resp_dict['time']) for j, laser in enumerate(las_pol): laser_cont = qr.TwoDResponseContainer(t2_dict) for i, tt2 in enumerate(resp_dict['t2axis']): reph = np.zeros((t13_fr_len, t13_fr_len), dtype=np.complex128, order='F') nonr = np.zeros((t13_fr_len, t13_fr_len), dtype=np.complex128, order='F') for name in signal_names: reph += resp_dict['r' + name][j][i] nonr += resp_dict['n' + name][j][i] from scipy import signal as sig window = 20 tuc = sig.tukey(window * 2, 1, sym=False) for k in range(len(reph)): reph[len(reph) - window:, k] *= tuc[window:] reph[k, len(reph) - window:] *= tuc[window:] nonr[len(nonr) - window:, k] *= tuc[window:] nonr[k, len(nonr) - window:] *= tuc[window:] reph = np.hstack((reph, np.zeros((reph.shape[0], test_pad)))) reph = np.vstack((reph, np.zeros((test_pad, reph.shape[1])))) nonr = np.hstack((nonr, np.zeros((nonr.shape[0], test_pad)))) nonr = np.vstack((nonr, np.zeros((test_pad, nonr.shape[1])))) onetwod_p = get_resp_object(respR=reph, respN=nonr, time_ax=t13_fr, rwa=resp_dict['rwa'], time_t2=tt2) laser_cont.set_spectrum(onetwod_p) resp_containers_part.append(laser_cont) return resp_containers_part, t2_dict
def test_TwoDSpectrumBase(self): """Testing basic functions of the TwoDSpectrumBase class """ t1 = qr.TimeAxis(0.0, 1000, 1.0) t3 = qr.TimeAxis(0.0, 1000, 1.0) twodB = TwoDSpectrumBase() twodB.set_axis_1(t1) twodB.set_axis_3(t3) data1 = numpy.zeros((t1.length, t3.length), dtype=qr.COMPLEX) data2 = numpy.zeros((t1.length, t3.length), dtype=qr.COMPLEX) data1[:, :] = 1.1 twodB._add_data(data1, resolution="off", dtype=qr.signal_TOTL) numpy.testing.assert_equal(twodB.data, data1) data2[:, :] = 2.2 with assert_raises(Exception): twodB.data = data2 twodB._allow_data_writing = True twodB.data = data2 numpy.testing.assert_equal(twodB.data, data2) with tempfile.TemporaryDirectory() as tdir: names = ["data.mat", "data.npy"] for name in names: fname = os.path.join(tdir, name) twodB.save_data(fname) twodB2 = TwoDSpectrumBase() twodB2.set_axis_1(t1) twodB2.set_axis_3(t3) twodB2.load_data(fname) numpy.testing.assert_equal(twodB.data, twodB2.data)
def step_when_8(context, time_step, N_dense): """ When I calculate EvolutionSuperOperator step by step using only PureDephasing D with {time_step} and {N_dense} """ # get the associated time axis and the relaxation tensor and Hamiltonian dt = float(time_step) N_dense = int(N_dense) Ntot = 1320 Nsteps = int(Ntot / N_dense) time = qr.TimeAxis(0, Ntot, 1.0) time2 = qr.TimeAxis(0, Nsteps, dt) context.time = time context.time2 = time2 HH = context.H DD = context.D print("Dephasing type: ", DD.dtype) # This tests if it is possible to ignore relaxation tensor in defining # evolution superoperator L = qr.qm.LindbladForm(HH, sbi=None) U = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD, mode="jit") U.set_dense_dt(N_dense) U1 = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD) with qr.eigenbasis_of(HH): for i in range(1, Nsteps): U.calculate_next() U1.data[i, :, :, :, :] = U.data[:, :, :, :] context.U = U1
def step_when_10(context, time_step, N_dense): """ When I calculate EvolutionSuperOperator step by step using PureDephasing D and Lindblad form L with {time_step} and {N_dense} """ HH = context.H L = context.L DD = context.D dt = float(time_step) N_dense = int(N_dense) Ntot = 1320 Nsteps = int(Ntot / N_dense) time2 = qr.TimeAxis(0, Nsteps, dt) context.time2 = time2 mode = "jit" print("Pure dephasing: ", DD.dtype) if mode == "jit": U = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD, mode="jit") U.set_dense_dt(N_dense) U1 = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD) with qr.eigenbasis_of(HH): for i in range(1, Nsteps): U.calculate_next() U1.data[i, :, :, :, :] = U.data[:, :, :, :] context.U = U1 elif mode == "all": U = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD, mode="all") U.set_dense_dt(N_dense) with qr.eigenbasis_of(HH): U.calculate() context.U = U
def step_given_12(context, N, step): """ And I have a TimeAxis of lenght {N} starting from zero with certain {step} """ length = int(N) step = float(step) vaxis = qr.TimeAxis(0.0, length, step) context.vaxis = vaxis context.length = length context.step = step
def step_when_12(context, time_step, N_dense): """ When I calculate EvolutionSuperOperator in one shot using only PureDephasing D with {time_step} and {N_dense} """ HH = context.H L = qr.qm.LindbladForm(HH, sbi=None) DD = context.D dt = float(time_step) N_dense = int(N_dense) Ntot = 1320 Nsteps = int(Ntot / N_dense) time2 = qr.TimeAxis(0, Nsteps, dt) context.time2 = time2 mode = "all" U = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD, mode=mode) U.set_dense_dt(N_dense) if mode == "all": with qr.eigenbasis_of(HH): U.calculate() context.U = U elif mode == "jit": U1 = qr.qm.EvolutionSuperOperator(time2, ham=HH, relt=L, pdeph=DD) with qr.eigenbasis_of(HH): for i in range(1, Nsteps): U.calculate_next() U1.data[i, :, :, :, :] = U.data[:, :, :, :] context.U = U1
def setUp(self, verbose=False): """Initializes the calculation """ self.verbose = verbose self.time = qr.TimeAxis(0, 1000, 1.0) self.temperature = 300 pars1 = dict(ftype="OverdampedBrownian", reorg=30, cortime=100, T=self.temperature) pars2 = dict(ftype="OverdampedBrownian", reorg=80, cortime=200, T=self.temperature) self.cf1 = qr.CorrelationFunction(self.time, pars1) self.cf2 = qr.CorrelationFunction(self.time, pars2)
n_loops = 1 totalSpec = int(n_per_loop * n_loops) t13_ax_ax_step = 1 t13_ax_ax_len = 300 t2_ax_step = 100 t2_ax_len = 100 padding = 1000 ####################################################################### # Setup paramaters ####################################################################### # The axis for time gaps 1 and 3 t13_ax_ax_count = int(t13_ax_ax_len / t13_ax_ax_step) + 1 t13_ax = qr.TimeAxis(0.0, t13_ax_ax_count, t13_ax_ax_step) # The axis for time gap 2 t2_ax_count = int(t2_ax_len / t2_ax_step) + 1 t2_ax = qr.TimeAxis(0.0, t2_ax_count, t2_ax_step) if _save_: try: os.mkdir(save_dir) except OSError: print("Creation of the directory %s failed" % save_dir) t1 = time.time() print("Calculating spectra from 0 to ", t2_ax_len, " fs\n") #######################################################################
# transition dipole moment m1.set_dipole(0, 1, [1.0, 0.0, 0.0]) # molecule 2 m2 = qr.Molecule([0.0, 11000.0]) m2.set_dipole(0, 1, [1.0, 0.0, 0.0]) # # Create aggregate of the two molecules # agg = qr.Aggregate(molecules=[m1, m2]) # # Define time span of the calculation # time = qr.TimeAxis(0.0, 10000, 1.0) # # Define bath correlation function # cpar = dict(ftype="OverdampedBrownian", cortime=30, reorg=200, T=300) with qr.energy_units("1/cm"): cf = qr.CorrelationFunction(time, cpar) # # Set the correlation function to the transitions on the molecules # m1.set_transition_environment((0, 1), cf) m2.set_transition_environment((0, 1), cf) #
# Number of times this is repeated n_loops = 2 totalSpec = int(n_per_loop * n_loops) t13_ax_step = 1 t13_ax_len = 200 t2_ax_step = 100 t2_ax_len = 100 ####################################################################### # Setup paramaters ####################################################################### # The axis for time gaps 1 and 3 t13_ax_count = int(t13_ax_len / t13_ax_step) + 1 t13_ax = qr.TimeAxis(0.0, t13_ax_count, t13_ax_step) # The axis for time gap 2 t2_ax_count = int(t2_ax_len / t2_ax_step) + 1 t2_ax = qr.TimeAxis(0.0, t2_ax_count, t2_ax_step) if _save_: try: os.mkdir(save_dir) os.mkdir(save_dir + 'spec') except OSError: print("Creation of the directory %s failed" % save_dir) t1 = time.time() print("Calculating spectra from 0 to ", t2_ax_len, " fs\n")
# the aggregate is built with single exciton states only agg.build(mult=1) # we print its Hamiltonian to check everything is alright H = agg.get_Hamiltonian() with qr.energy_units("1/cm"): print(H) ############################################################################### # # EXCITED STATE DYNAMICS: Lindblad relaxation between eigenstates # ############################################################################### # time span of the excited state evolution (later t2 time of the 2D spectrum) t2_axis = qr.TimeAxis(0.0, 100, 10.0) # Lindblad relaxation operator with qr.eigenbasis_of(H): K = qr.qm.ProjectionOperator(1, 2, dim=H.dim) rates = [1.0 / 200.0] sbi = qr.qm.SystemBathInteraction(sys_operators=[K], rates=rates) L = qr.qm.LindbladForm(H, sbi) eUt = qr.EvolutionSuperOperator(time=t2_axis, ham=H, relt=L) eUt.set_dense_dt(10) eUt.calculate()
import numpy import quantarhei as qr from quantarhei.models.modelgenerator import ModelGenerator print(""" ******************************************************************************* * * * Redfield Theory Demo * * * ******************************************************************************* """) Nt = 1000 dt = 1.0 time = qr.TimeAxis(0.0, Nt, dt) mg = ModelGenerator() agg = mg.get_Aggregate_with_environment(name="pentamer-1_env", timeaxis=time) agg.build() sbi = agg.get_SystemBathInteraction() ham = agg.get_Hamiltonian() ham.set_name("Hamiltonian") print(">>> Hamiltonian ") with qr.energy_units("1/cm"): print(ham) print("""
#import aceto #from aceto.lab_settings import lab_settings r = 5 numMol = 8 coreN = 1 repeatN = 2 dipoleStrength = 5 staticDis = 300 reorganisation = 100 t2Step = 200 t2Count = 2 t13Step = 2 t13Count = 300 t2s = qr.TimeAxis(0.0, t2Count, t2Step) t13 = qr.TimeAxis(0.0, t13Count, t13Step) timeTotal = qr.TimeAxis(0.0, 3 * t13Count, t13Step) two_pi = np.pi * 2 proteinDis = 8.7 difference = 0.6 temperature = 300 params = dict(ftype="OverdampedBrownian", T=temperature, reorg=reorganisation, cortime=100.0) with qr.energy_units('1/cm'): cf = qr.CorrelationFunction(timeTotal, params) #cf = CorrelationFunction(ta, params)
import os import matplotlib.pyplot as plt import quantarhei as qr dirn = "c01" pre_in = os.path.join(dirn,"out") filename = "pathways_20.0.qrp" 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()
rates=(1.0 / 200, 1.0 / 100.0, 1.0 / 150)) agg.set_SystemBathInteraction(sbi) agg.build() ham = agg.get_Hamiltonian() rt = qr.qm.LindbladForm(ham, sbi) # as_operators=False) print("...done") # # Time interval for evolution superoperator # time_so = qr.TimeAxis(0.0, 11, 50.0) time_tot = qr.TimeAxis(0.0, 1000, 0.5) print("Calculating evolution superoperator:") # # calculation of the evolution superoperator # eS = qr.qm.EvolutionSuperOperator(time_so, ham, rt) eS.set_dense_dt(100) eS.calculate() print("...done") print("Reference calculation:") #
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)
mod.set_HR(1, hr_factor) mol.set_transition_width((0, 1), width) # # 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) #
# setting system bath interaction to provide lineshape with qr.energy_units("1/cm"): mol.set_transition_width((0, 1), width) # building aggregate agg.build() HH = agg.get_Hamiltonian() # check the aggregate print(agg) # # calculation of absorption spectrum # time1 = qr.TimeAxis(0.0, 1000, 5.0) absc = qr.MockAbsSpectrumCalculator(time1, system=agg) 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=[9000.0, 13000.0, 0.0, 1.1]) spctrm.savefig("abs.png") # # calculation of 2D spectrum # time2 = qr.TimeAxis(0.0, 10, 10.0)
# -*- coding: utf-8 -*- import quantarhei as qr import numpy ta = qr.TimeAxis(0.0, 1000, 1.0) """ Absorption of a monomeric two-level molecule """ cfce_params1 = dict(ftype="OverdampedBrownian", reorg=20.0, cortime=100.0, T=100, matsubara=20) en = 12000.0 e_units = qr.energy_units("1/cm") with e_units: m = qr.Molecule("Molecule", [0.0, en]) with qr.energy_units("1/cm"): cfce1 = qr.CorrelationFunction(ta, cfce_params1) m.set_egcf((0, 1), cfce1) m.set_dipole(0, 1, [0.0, 1.0, 0.0])
LF_el = qr.qm.ElectronicLindbladForm(HHe, sbi_el, as_operators=True) # # Laboratory setup # from quantarhei import LabSetup from quantarhei.utils.vectors import X #, Y, Z lab = LabSetup() lab.set_polarizations(pulse_polarizations=[X, X, X], detection_polarization=X) # # We define time axis for propagation # time_axis = qr.TimeAxis(0.0, propagation_N_steps, propagation_dt) agg_el.diagonalize() # # Absorption Spectrum calculated by the pathway method # # initial conditions before excitation rho0 = agg_el.get_DensityMatrix(condition_type="thermal", temperature=0.0) # electronic Hamiltonian ham = agg_el.get_Hamiltonian() # first order Liouville pathways pthways = agg_el.liouville_pathways_1(lab=lab, ham=ham, etol=1.0e-5, verbose=0) # absorption spectrum calculator mac = qr.MockAbsSpectrumCalculator(time_axis, system=agg_el)
_save_2D_ = False ############################################################################### # # MODEL: Simple dimer of molecules # ############################################################################### Nt2 = 50 dt2 = 20 Npad = 0 Nt = Nt2 dt = dt2 t_axis = qr.TimeAxis(0.0, Nt2, dt2) with qr.energy_units("1/cm"): # two two-level molecules m1 = qr.Molecule([0.0, 12000.0]) m2 = qr.Molecule([0.0, 12300.0]) # correlation functions the environment # cfce_params1 = dict(ftype="OverdampedBrownian", reorg=40.0, cortime=100.0, T=100, matsubara=20) cfce_params2 = dict(ftype="OverdampedBrownian", reorg=40.0,