def generate_heom(reorg_energy): print str(reorg_energy) + ' at ' + str(tu.getTime()) print '' model_heom = DQDHEOMModelSparse(Gamma_L, Gamma_R, bias, T_c, beta=beta, environment=environment(reorg_energy, beta, K), \ K=K, tc=True, trunc_level=N) heom_matrix = model_heom.heom_matrix() np.savez('data/F2_reorg_energy_heom_data_K'+str(K)+'_vals_'+str(re_min)+'-'+str(re_max)+'_'+str(reorg_energy)+'.npz', reorg_energy=reorg_energy, \ indices=heom_matrix.indices, elements=heom_matrix.data, indptrs=heom_matrix.indptr)
def calculate_FCS(reorg_energy): print str(reorg_energy) + ' at ' + str(tu.getTime()) data_pt = np.load('data/F2_reorg_energy_heom_data_K'+str(K)+'_vals_'+str(re_min)+'-'+str(re_max)+'_'+str(reorg_energy)+'.npz') elements = data_pt['elements'] indices = data_pt['indices'] indptrs = data_pt['indptrs'] heom_matrix = sp.csr_matrix((elements, indices, indptrs), shape=shape) solver = FCSSolver(heom_matrix, jump_matrix, dv_pops) mean_heom = solver.mean() F2_heom = solver.second_order_fano_factor() #coh_heom[i] = np.abs(model_heom.heom_solver.extract_system_density_matrix(solver.ss)[1,2]) return [mean_heom, F2_heom, 0]
num_matsubara_freqs = 1 # model = DQDHEOMModel(Gamma_L, Gamma_R, bias, T_c, beta=beta[0], drude_reorg_energy=reorg_energy, drude_cutoff=cutoff, \ # num_matsubara_freqs=0, temperature_correction=True, sites_to_couple=np.array([0,1,1])) bias_values = np.linspace(-1, 1, 100) F2 = np.zeros((len(beta)+1, bias_values.size)) def calculate_F2(model): solver = FCSSolver(model.heom_matrix(), model.jump_matrix(), model.dv_pops) return solver.second_order_fano_factor(0) from multiprocessing import Pool pool = Pool(processes=4) for j,B in enumerate(beta): print 'for beta = ' + str(B) + ' at ' + str(tu.getTime()) models = [] for E in bias_values: models.append(DQDHEOMModel(Gamma_L, Gamma_R, E, T_c, beta=B, drude_reorg_energy=reorg_energy, drude_cutoff=cutoff, \ num_matsubara_freqs=num_matsubara_freqs, temperature_correction=True, sites_to_couple=np.array([0,1,1]))) F2[j+1] = pool.map(calculate_F2, models) pool.close(); pool.join() print 'Saving...' np.savez('../data/HEOM_F2_bias_drude_K_'+str(num_matsubara_freqs)+'.npz', F2=F2, bias_values=bias_values, \ beta=beta, temperature=temperature)
time_propagator = np.zeros((2, 2)) time_propagator[0, 0] = -k01 time_propagator[0, 1] = k10 time_propagator[1, 1] = -k10 time_propagator[1, 0] = k01 time_step = t[1] - t[0] dynamics = te.liouvillian_time_evolution(np.array([1, 0]), 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.
''' Created on 1 Jun 2016 @author: rstones ''' import numpy as np import matplotlib.pyplot as plt import quant_mech.time_evolution as te import quant_mech.time_utils as tutils from quant_mech.hierarchy_solver import HierarchySolver np.set_printoptions(precision=3, linewidth=150, suppress=True) print 'Calculating time evolution...' start_time = tutils.getTime() time_step = 0.01 duration = 5 # picoseconds average_site_CT_energies = np.array([15260., 15190., 15000., 15100., 15030., 15020., 15992., 16132.]) # site-CT couplings couplings = np.array([[0,150.,-42.,-55.,-6.,17.,0,0], [0,0,-56.,-36.,20.,-2.,0,0], [0,0,0,7.,46.,-4.,70.,0], [0,0,0,0,-5.,37.,0,0], [0,0,0,0,0,-3.,70.,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,40.], [0,0,0,0,0,0,0,0]]) system_hamiltonian = np.diag(average_site_CT_energies) + couplings + couplings.T
site_reorg_energies = np.array([total_site_reorg_energy, total_site_reorg_energy, total_site_reorg_energy, \ total_site_reorg_energy, total_site_reorg_energy, total_site_reorg_energy]) lbf_fn = '../../data/PSIIRC_lbfs_' + str( int(temperature)) + 'K_site_reorg_' + str( int(total_site_reorg_energy)) + '_cutoff_freq_' + str( int(cutoff_freq)) + '_no_modes_data.npz' #lbf_fn = '../../data/PSIIRC_lbfs_' + str(int(temperature)) + 'K_site_reorg_' + str(int(total_site_reorg_energy)) + '_single_mode_data.npz' try: data = np.load(lbf_fn) lbf = data['lbf'] lbf_dot = data['lbf_dot'] lbf_dot_dot = data['lbf_dot_dot'] time = data['time'] except IOError: print 'Starting lbf calculations at ' + str(time_utils.getTime()) lbf_coeffs = os.lbf_coeffs(site_drude_reorg_energy, cutoff_freq, temperature, single_mode_params, 100) lbf = os.site_lbf_ed(time, lbf_coeffs) lbf_dot = os.site_lbf_dot_ed(time, lbf_coeffs) lbf_dot_dot = os.site_lbf_dot_dot_ed(time, lbf_coeffs) print 'Finished calculating lbfs at ' + str(time_utils.getTime()) np.savez(lbf_fn, lbf=lbf, lbf_dot=lbf_dot, lbf_dot_dot=lbf_dot_dot, time=time) # calculate MRT rates evals, evecs = utils.sorted_eig(hamiltonian[:6, :6])
time = np.arange(0, duration+time_step, time_step) system_hamiltonian = np.array([[100., 20.], [20., 0]]) cutoff_freq = 53. temperature = 300. 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.
drude_reorg_energy = 0.015 # 0.00147 drude_cutoff = 50. # 5. # OBOscillator(drude_reorg_energy, drude_cutoff, beta, K=K) def environment(beta, K): return [(), \ (OBOscillator(drude_reorg_energy, drude_cutoff, beta, K=K), UBOscillator(mode_freq, hr_factor, damping, beta, K=K),), \ (OBOscillator(drude_reorg_energy, drude_cutoff, beta, K=K), UBOscillator(mode_freq, hr_factor, damping, beta, K=K),)] model = DQDHEOMModelSparse(Gamma_L, Gamma_R, bias, T_c, beta=beta[0], environment=environment(beta[0], K), \ K=K, tc=True, trunc_level=6) bias_values = np.linspace(-10, 10, 20) mean = np.zeros((len(beta)+1, bias_values.size)) F2 = np.zeros((len(beta)+1, bias_values.size)) print "Starting calculation at " + str(tu.getTime()) for j,B in enumerate(beta): print 'for beta = ' + str(B) + ' at ' + str(tu.getTime()) model.beta = B model.environment = environment(B, K) for i,E in enumerate(bias_values): print E model.bias = E solver = FCSSolver(model.heom_matrix(), model.jump_matrix(), model.dv_pops) try: mean[j+1,i] = solver.mean() F2[j+1,i] = solver.second_order_fano_factor() except RuntimeError: print "SINGULAR ERROR!!!!!!!"
return np.array([[energy_gap / 2., coupling], [coupling, -energy_gap / 2.]]) reorg_energy = 100. cutoff_freq = 53. temperature = 300. energy_gap_values = np.logspace(0, 3, 10) coupling = 20. hamiltonians = [ hamiltonian(energy_gap, coupling) for energy_gap in energy_gap_values ] print 'Calculating line broadening function at ' + str(time_utils.getTime()) time = np.linspace(0, 10, 1000000) num_expansion_terms = 500 lbf_fn = '../../data/hierarchy_MRT_comparison_lbf_data.npz' try: data = np.load(lbf_fn) lbf = data['lbf'] lbf_dot = data['lbf_dot'] lbf_dot_dot = data['lbf_dot_dot'] except IOError: lbf_coeffs = os.lbf_coeffs(reorg_energy, cutoff_freq, temperature, None, num_expansion_terms) lbf = os.site_lbf_ed(time, lbf_coeffs) lbf_dot = os.site_lbf_dot_ed(time, lbf_coeffs) lbf_dot_dot = os.site_lbf_dot_ed(time, lbf_coeffs) np.savez(lbf_fn,
# mode_params = [] #[(1111., 0.0578, 50.)] K = 0 environment = [] if mode_params: # assuming that there is a single identical mode on each site environment = [(OBOscillator(reorg_energy, cutoff_freq, beta, K=K), UBOscillator(mode_params[0][0], mode_params[0][1], mode_params[0][2], beta, K=K)), \ (OBOscillator(reorg_energy, cutoff_freq, beta, K=K), UBOscillator(mode_params[0][0], mode_params[0][1], mode_params[0][2], beta, K=K))] else: environment = [(OBOscillator(reorg_energy, cutoff_freq, beta, K=K),), (OBOscillator(reorg_energy, cutoff_freq, beta, K=K),)] hs = HierarchySolver(system_hamiltonian, environment, beta, num_matsubara_freqs=K, temperature_correction=False) #hs = HierarchySolverNonRenorm(system_hamiltonian, environment, beta, num_matsubara_freqs=K, temperature_correction=False) hs.truncation_level = 30 print 'Calculating time evolution...' start = tutils.getTime() init_state = np.array([[1.,0],[0,0]]) #init_state = np.dot(hs.system_evectors.T, np.dot(init_state, hs.system_evectors)) hs.init_system_dm = init_state dm_history, time = hs.calculate_time_evolution(time_step, duration) #exciton_dm_history = hs.transform_to_exciton_basis(dm_history) end = tutils.getTime() print 'Calculation took ' + str(tutils.duration(end, start)) # convert time in inverse wavenums to picoseconds time /= utils.WAVENUMS_TO_INVERSE_PS fig,(ax1,ax2) = plt.subplots(1, 2)
# define model def hamiltonian(energy_gap, coupling): return np.array([[energy_gap/2., coupling], [coupling, -energy_gap/2.]]) reorg_energy = 100. cutoff_freq = 53. temperature = 300. energy_gap_values = np.logspace(0, 3, 10) coupling = 20. hamiltonians = [hamiltonian(energy_gap, coupling) for energy_gap in energy_gap_values] print 'Calculating line broadening function at ' + str(time_utils.getTime()) time = np.linspace(0, 10, 1000000) num_expansion_terms = 500 lbf_fn = '../../data/hierarchy_MRT_comparison_lbf_data.npz' try: data = np.load(lbf_fn) lbf = data['lbf'] lbf_dot = data['lbf_dot'] lbf_dot_dot = data['lbf_dot_dot'] except IOError: lbf_coeffs = os.lbf_coeffs(reorg_energy, cutoff_freq, temperature, None, num_expansion_terms) lbf = os.site_lbf_ed(time, lbf_coeffs) lbf_dot = os.site_lbf_dot_ed(time, lbf_coeffs) lbf_dot_dot = os.site_lbf_dot_ed(time, lbf_coeffs) np.savez(lbf_fn, lbf=lbf, lbf_dot=lbf_dot, lbf_dot_dot=lbf_dot_dot, time=time)
# print FCSSolver.stationary_state(hm, model_heom.dv_pops)[:9] reorg_energy_values = np.logspace(-6, 0, 60) F2_heom = np.zeros((len(beta), reorg_energy_values.size)) F2_pert = np.zeros((len(beta), reorg_energy_values.size)) coh_heom = np.zeros((len(beta), reorg_energy_values.size)) coh_pert = np.zeros((len(beta), reorg_energy_values.size)) mean_heom = np.zeros((len(beta), reorg_energy_values.size)) mean_pert = np.zeros((len(beta), reorg_energy_values.size)) for j,B in enumerate(beta): print "calculating for beta = " + str(B) model_heom.beta = B model_pert.beta = B for i,E in enumerate(reorg_energy_values): print str(E) + ' at ' + str(tu.getTime()) model_heom.environment = environment(E, B, K) try: solver = FCSSolver(model_heom.heom_matrix(), model_heom.jump_matrix(), model_heom.dv_pops) mean_heom[j,i] = solver.mean() F2_heom[j,i] = solver.second_order_fano_factor() coh_heom[j,i] = np.abs(model_heom.heom_solver.extract_system_density_matrix(solver.ss)[1,2]) except ArpackNoConvergence: print "Convergence error!" model_pert.spectral_density = drude_spectral_density(E, cutoff) solver_pert = DenseFCSSolver(model_pert.liouvillian(), model_pert.jump_matrix(), np.array([1,1,1,0,0])) mean_pert[j,i] = solver_pert.mean() F2_pert[j,i] = solver_pert.second_order_fano_factor(0) coh_pert[j,i] = np.abs(solver_pert.ss[3] + solver_pert.ss[4]) # fname = '../../data/HEOM_weak_coupling_F2_reorg_energy_drude_T2.7_N6_K7.npz'
# init_state[0,0] = 1. # exciton basis # init_state = np.dot(hs.system_evectors, np.dot(init_state, hs.system_evectors.T)) # transform to site basis for HEOM calculation # dm_history, time = hs.converged_time_evolution(init_state, truncation_level, truncation_level, time_step, duration) # exciton_dm_history = hs.transform_to_exciton_basis(dm_history) # np.savez('../../data/PSIIRC_HEOM_dynamics_reorg_energy_'+str(int(reorg_energy))+'_wavenums.npz', exciton_dm_history=exciton_dm_history, \ # time=time, init_state=init_state, reorg_energy=reorg_energy, cutoff_freq=cutoff_freq, temperature=temperature, \ # system_hamiltonian=system_hamiltonian) # try different cutoff freqs reorg_energy = 35. cutoff_freq_values = [40., 70., 100.] temperature = 300. for cutoff_freq in cutoff_freq_values: print 'Started calculating HEOM dynamics for cutoff_freq = ' + str( cutoff_freq) + 'cm-1 at ' + str(tutils.getTime()) hs = HierarchySolver(system_hamiltonian, reorg_energy, cutoff_freq, temperature) init_state = np.zeros(system_hamiltonian.shape) init_state[0, 0] = 1. # exciton basis init_state = np.dot(hs.system_evectors, np.dot(init_state, hs.system_evectors.T) ) # transform to site basis for HEOM calculation dm_history, time = hs.converged_time_evolution(init_state, truncation_level, truncation_level, time_step, duration) exciton_dm_history = hs.transform_to_exciton_basis(dm_history) np.savez('../../data/PSIIRC_HEOM_dynamics_cutoff_freq_'+str(int(cutoff_freq))+'_wavenums.npz', exciton_dm_history=exciton_dm_history, \ time=time, init_state=init_state, reorg_energy=reorg_energy, cutoff_freq=cutoff_freq, temperature=temperature, \ system_hamiltonian=system_hamiltonian)
for i,cutoff_freq in enumerate(cutoff_freqs): total_site_reorg_energy = site_drude_reorg_energy# + single_mode_params[0][0]*single_mode_params[0][1] site_reorg_energies = np.array([total_site_reorg_energy, total_site_reorg_energy, total_site_reorg_energy, \ total_site_reorg_energy, total_site_reorg_energy, total_site_reorg_energy]) lbf_fn = '../../data/PSIIRC_lbfs_' + str(int(temperature)) + 'K_site_reorg_' + str(int(total_site_reorg_energy)) + '_cutoff_freq_'+str(int(cutoff_freq))+'_no_modes_data.npz' #lbf_fn = '../../data/PSIIRC_lbfs_' + str(int(temperature)) + 'K_site_reorg_' + str(int(total_site_reorg_energy)) + '_single_mode_data.npz' try: data = np.load(lbf_fn) lbf = data['lbf'] lbf_dot = data['lbf_dot'] lbf_dot_dot = data['lbf_dot_dot'] time = data['time'] except IOError: print 'Starting lbf calculations at ' + str(time_utils.getTime()) lbf_coeffs = os.lbf_coeffs(site_drude_reorg_energy, cutoff_freq, temperature, single_mode_params, 100) lbf = os.site_lbf_ed(time, lbf_coeffs) lbf_dot = os.site_lbf_dot_ed(time, lbf_coeffs) lbf_dot_dot = os.site_lbf_dot_dot_ed(time, lbf_coeffs) print 'Finished calculating lbfs at ' + str(time_utils.getTime()) np.savez(lbf_fn, lbf=lbf, lbf_dot=lbf_dot, lbf_dot_dot=lbf_dot_dot, time=time) # calculate MRT rates evals,evecs = utils.sorted_eig(hamiltonian[:6,:6]) exciton_reorg_energies = np.array([os.exciton_reorg_energy(exciton, site_reorg_energies) for exciton in evecs]) # print evals - exciton_reorg_energies # evals,evecs = utils.sort_evals_evecs(evals-exciton_reorg_energies, evecs) # print evals
hs = HierarchySolver(system_hamiltonian, reorg_energy, cutoff_freq, temperature, jump_operators=jump_operators, jump_rates=jump_rates) # start_time = tutils.getTime() # print 'Calculating steady state...' # steady_state = hs.calculate_steady_state(6,6) # print steady_state # # end_time = tutils.getTime() # print 'Calculation took ' + str(tutils.duration(end_time, start_time)) start_time = tutils.getTime() print 'Calculating time evolution...' dm_history, time = hs.hierarchy_time_evolution(np.array([[0, 0, 0, 0], [0, 1., 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]), 8, 8, 0.005, 15., sparse=True) end_time = tutils.getTime() print 'Calculation took ' + str(tutils.duration(end_time, start_time)) print time.shape print dm_history.shape for i in range(4):
from quant_mech.OBOscillator import OBOscillator import quant_mech.time_utils as tu from scipy.sparse.linalg.eigen.arpack.arpack import ArpackNoConvergence import sys # get task_id task_id = sys.argv[1] try: task_id = int(task_id) except TypeError: print 'ERROR: Task id was None' sys.exit(0) stride = 1 print 'JOB ' + str(task_id) + ': starting calculation at ' + str(tu.getTime()) Gamma_L = 0.1 # meV Gamma_R = 2.5e-3 # meV bias = 0.2 T_c = 0.1 # meV temperature = [1.4, 2.7, 12.] # Kelvin k_B = constants.physical_constants["Boltzmann constant in eV/K"][0] * 1.e3 # meV / Kelvin beta = [1. / (k_B * T) for T in temperature][1:2] beta = beta[0] #reorg_energy = 0.000147 cutoff = 5. # meV N = 6 K = 6 data = np.load('../data/F2_reorg_energy_heom_data_N'+str(N)+'_K'+str(K)+'.npz')
# print 'Started calculating HEOM dynamics for reorg_energy = ' + str(reorg_energy) + 'cm-1 at ' + str(tutils.getTime()) # hs = HierarchySolver(system_hamiltonian, reorg_energy, cutoff_freq, temperature) # init_state = np.zeros(system_hamiltonian.shape) # init_state[0,0] = 1. # exciton basis # init_state = np.dot(hs.system_evectors, np.dot(init_state, hs.system_evectors.T)) # transform to site basis for HEOM calculation # dm_history, time = hs.converged_time_evolution(init_state, truncation_level, truncation_level, time_step, duration) # exciton_dm_history = hs.transform_to_exciton_basis(dm_history) # np.savez('../../data/PSIIRC_HEOM_dynamics_reorg_energy_'+str(int(reorg_energy))+'_wavenums.npz', exciton_dm_history=exciton_dm_history, \ # time=time, init_state=init_state, reorg_energy=reorg_energy, cutoff_freq=cutoff_freq, temperature=temperature, \ # system_hamiltonian=system_hamiltonian) # try different cutoff freqs reorg_energy = 35. cutoff_freq_values = [40., 70., 100.] temperature = 300. for cutoff_freq in cutoff_freq_values: print 'Started calculating HEOM dynamics for cutoff_freq = ' + str(cutoff_freq) + 'cm-1 at ' + str(tutils.getTime()) hs = HierarchySolver(system_hamiltonian, reorg_energy, cutoff_freq, temperature) init_state = np.zeros(system_hamiltonian.shape) init_state[0,0] = 1. # exciton basis init_state = np.dot(hs.system_evectors, np.dot(init_state, hs.system_evectors.T)) # transform to site basis for HEOM calculation dm_history, time = hs.converged_time_evolution(init_state, truncation_level, truncation_level, time_step, duration) exciton_dm_history = hs.transform_to_exciton_basis(dm_history) np.savez('../../data/PSIIRC_HEOM_dynamics_cutoff_freq_'+str(int(cutoff_freq))+'_wavenums.npz', exciton_dm_history=exciton_dm_history, \ time=time, init_state=init_state, reorg_energy=reorg_energy, cutoff_freq=cutoff_freq, temperature=temperature, \ system_hamiltonian=system_hamiltonian) print 'Calculations finished'
hs = HierarchySolver( system_hamiltonian, reorg_energy, cutoff_freq, beta, underdamped_mode_params=mode_params, num_matsubara_freqs=1, temperature_correction=True, sites_to_couple=np.array([1, 1]), ) hs.truncation_level = 11 print hs.system_dimension ** 2 * hs.number_density_matrices() print "Calculating time evolution..." start = tutils.getTime() init_state = np.array([[1.0, 0], [0, 0]]) # init_state = np.dot(hs.system_evectors.T, np.dot(init_state, hs.system_evectors)) # print init_state hs.init_system_dm = init_state hs.truncation_level = 11 dm_history, time = hs.calculate_time_evolution(time_step, duration) # exciton_dm_history = hs.transform_to_exciton_basis(dm_history) end = tutils.getTime() print "Calculation took " + str(tutils.duration(end, start)) # convert time in inverse wavenums to picoseconds time /= utils.WAVENUMS_TO_INVERSE_PS
def environment(beta, K): return [(), \ (OBOscillator(reorg_energy, cutoff, beta, K=K),), \ (OBOscillator(reorg_energy, cutoff, beta, K=K),)] model = DQDHEOMModelSparse(Gamma_L, Gamma_R, bias, T_c, beta=beta[0], environment=environment(beta[0], K), \ K=K, tc=True, trunc_level=5) bias_values = np.linspace(-1, 1, 200) * 10 mean = np.zeros((len(beta)+1, bias_values.size)) F2 = np.zeros((len(beta)+1, bias_values.size)) #coherence = np.zeros((len(beta)+1, bias_values.size)) site_steady_states = np.zeros((len(beta)+1, bias_values.size, 9), dtype='complex128') print "Starting calculation at " + str(tu.getTime()) for j,B in enumerate(beta): print 'for beta = ' + str(B) model.beta = B model.environment = environment(B, K) for i,E in enumerate(bias_values): #print E model.bias = E solver = FCSSolver(model.heom_matrix(), model.jump_matrix(), model.dv_pops) try: mean[j+1,i] = solver.mean() F2[j+1,i] = solver.second_order_fano_factor() #coherence[j+1,i] = solver.ss[3].squeeze() + solver.ss[4].squeeze() site_steady_states[j+1,i] = solver.ss[:9].squeeze() except RuntimeError: