def test_kmc_algorithm(self): np.random.seed( 0 ) # set random seed in order for the examples to reproduce the exact references transitions = [ Transition( s1, gs, tdm=[0.5, 0.2], # a.u. reorganization_energy=0.08, # eV symmetric=True) ] vibrational_model = MarcusModel(transitions=transitions, temperature=300) # Kelvin # list of transfer functions by state self.system.process_scheme = [ GoldenRule(initial_states=(s1, gs), final_states=(gs, s1), electronic_coupling_function=forster_coupling_extended, description='Forster', arguments={ 'ref_index': 2, 'longitude': 2, 'n_divisions': 30, 'transitions': transitions }, vibrations=vibrational_model), DecayRate(initial_state=s1, final_state=gs, decay_rate_function=einstein_radiative_decay, arguments={'transitions': transitions}, description='singlet_radiative_decay') ] self.system.cutoff_radius = 10.0 # interaction cutoff radius in Angstrom # some system analyze functions system_test_info(self.system) trajectories = calculate_kmc( self.system, num_trajectories=10, # number of trajectories that will be simulated max_steps=100, # maximum number of steps for trajectory allowed silent=True) # Results analysis analysis = TrajectoryAnalysis(trajectories) print('diffusion coefficient: {:9.5f} Angs^2/ns'.format( analysis.diffusion_coefficient('s1'))) print('lifetime: {:9.5f} ns'.format( analysis.lifetime('s1'))) print('diffusion length: {:9.5f} Angs'.format( analysis.diffusion_length('s1'))) print('diffusion tensor (Angs^2/ns)') print(analysis.diffusion_coeff_tensor('s1')) print('diffusion length square tensor (Angs)') print(analysis.diffusion_length_square_tensor('s1')) test = { 'diffusion coefficient': np.around(analysis.diffusion_coefficient('s1'), decimals=4), 'lifetime': np.around(analysis.lifetime('s1'), decimals=4), 'diffusion length': np.around(analysis.diffusion_length('s1'), decimals=4), 'diffusion tensor': np.around(analysis.diffusion_coeff_tensor('s1', unit_cell=[[0.0, 0.5], [0.2, 0.0]]), decimals=4).tolist(), 'diffusion length tensor': np.around(analysis.diffusion_length_square_tensor( 's1', unit_cell=[[0.0, 0.5], [0.2, 0.0]]), decimals=6).tolist() } print(test) ref = { 'diffusion coefficient': 1586.4162, 'lifetime': 0.3621, 'diffusion length': 47.9375, 'diffusion tensor': [[2048.6421, 3.4329], [3.4329, 1124.1904]], 'diffusion length tensor': [[3142.8, 42.0], [42.0, 1453.2]] } self.assertDictEqual(ref, test)
def test_kmc_algorithm(self): np.random.seed(0) # set random seed in order for the examples to reproduce the exact references transitions = [Transition(s1, gs, tdm=[0.3, 0.1], # a.u. reorganization_energy=0.08, # eV symmetric=True)] marcus = MarcusModel(transitions=transitions, temperature=300) # Kelvin # list of transfer functions by state self.system.process_scheme = [GoldenRule(initial_states=(s1, gs), final_states=(gs, s1), electronic_coupling_function=forster_coupling_extended, description='Forster', arguments={'ref_index': 2, 'longitude': 2, 'n_divisions': 30, 'transitions': transitions}, vibrations=marcus ), DecayRate(initial_state=s1, final_state=gs, decay_rate_function=einstein_radiative_decay, arguments={'transitions': transitions}, description='singlet_radiative_decay') ] self.system.cutoff_radius = 10.0 # interaction cutoff radius in Angstrom # some system analyze functions system_test_info(self.system) trajectories = calculate_kmc(self.system, num_trajectories=10, # number of trajectories that will be simulated max_steps=100, # maximum number of steps for trajectory allowed silent=True) # Results analysis analysis = TrajectoryAnalysis(trajectories) print('diffusion coefficient: {:9.5f} Angs^2/ns'.format(analysis.diffusion_coefficient('s1'))) print('lifetime: {:9.5f} ns'.format(analysis.lifetime('s1'))) print('diffusion length: {:9.5f} Angs'.format(analysis.diffusion_length('s1'))) print('diffusion tensor (Angs^2/ns)') print(analysis.diffusion_coeff_tensor('s1')) print('diffusion length square tensor (Angs)') print(analysis.diffusion_length_square_tensor('s1')) test = {'diffusion coefficient': np.around(analysis.diffusion_coefficient('s1'), decimals=4), 'lifetime': np.around(analysis.lifetime('s1'), decimals=4), 'diffusion length': np.around(analysis.diffusion_length('s1'), decimals=4), 'diffusion tensor': np.around(analysis.diffusion_coeff_tensor('s1', unit_cell=[[5.0, 1.0], [1.0, 5.0]]), decimals=4).tolist(), 'diffusion length tensor': np.around(analysis.diffusion_length_square_tensor('s1', unit_cell=[[5.0, 1.0], [1.0, 5.0]]), decimals=4).tolist() } ref = {'diffusion coefficient': 120.7623, 'lifetime': 2.1215, 'diffusion length': 33.0968, 'diffusion tensor': [[198.6035, -72.076], [-72.076, 98.3641]], 'diffusion length tensor': [[1606.8, -728.0], [-728.0, 1144.0]] } self.maxDiff = None __import__('sys').modules['unittest.util']._MAX_LENGTH = 999999999 self.assertDictEqual(ref, test)
# Electronic couplings in eV for the closest neighbor molecule in the indicated direction singlet_couplings = [12.61e-3, # a 41.85e-3, # ab 41.85e-3, # ab 27.51e-3] # b triplet_couplings = [0.0e-3, # a 7.2e-3, # ab 7.2e-3, # ab 1.2e-3] # b # Vibrations vibrational_model = MarcusModel(reorganization_energies={(gs, s1): 0.07, (s1, gs): 0.07, (gs, t1): 0.07, # assuming triplet same reorganization (t1, gs): 0.07}, # energy as singlet temperature=300) ################################################################################# # 2D model (plane a-b) , not diffusion in C molecule = Molecule() system = crystal_system(molecules=[molecule, molecule], # molecule to use as reference scaled_site_coordinates=[[0.0, 0.0], [0.5, 0.5]], unitcell=[[7.3347, 0.0000], [-0.2242, 6.0167]], dimensions=[4, 4], # supercell size orientations=[[0.0, 0.0, np.pi/8], [0.0, 0.0, -np.pi/8]]) # if element is None then random, if list then Rx Ry Rz
# set initial exciton system.add_excitation_index(s1, 0) system.add_excitation_index(s1, 1) # set additional system parameters system.process_scheme = [ GoldenRule( initial_states=(s1, gs), final_states=(gs, s1), electronic_coupling_function=forster_coupling, description='Forster coupling', arguments={ 'ref_index': 1, 'transitions': transitions }, vibrations=MarcusModel(transitions=transitions) # eV ), DecayRate(initial_state=s1, final_state=gs, decay_rate_function=einstein_radiative_decay, arguments={'transitions': transitions}, description='custom decay rate') ] system.cutoff_radius = 8 # interaction cutoff radius in Angstrom # some system analyze functions system_test_info(system) visualize_system(system) # do the kinetic Monte Carlo simulation
num_trajectories = 500 # number of trajectories that will be simulated max_steps = 100 # maximum number of steps for trajectory allowed system = regular_system(molecule=molecule, lattice={'size': [3, 3], 'parameters': [3.0, 3.0]}, # Angstroms orientation=[0, 0, 0]) visualize_system(system) system.cutoff_radius = 4.0 # Angstroms system.process_scheme = [GoldenRule(initial_states=(s1, gs), final_states=(gs, s1), electronic_coupling_function=forster_coupling, arguments={'ref_index': 1, 'transition_moment': transition_moment}, vibrations=MarcusModel(), description='forster'), DecayRate(initial_state=s1, final_state=gs, decay_rate_function=einstein_radiative_decay, arguments={'transition_moment': transition_moment}, description='decay')] system.add_excitation_index(s1, 1) system_test_info(system) trajectories = calculate_kmc(system, num_trajectories=5, # number of trajectories that will be simulated max_steps=1000, # maximum number of steps for trajectory allowed silent=False)
def test_kmc_algorithm_2(self): np.random.seed( 0 ) # set random seed in order for the examples to reproduce the exact references transitions = [ Transition(s1, gs, tdm=[0.01], reorganization_energy=0.07, symmetric=True) ] # set additional system parameters self.system.process_scheme = [ GoldenRule(initial_states=(s1, gs), final_states=(gs, s1), electronic_coupling_function=forster_coupling, description='Forster coupling', arguments={ 'ref_index': 1, 'transitions': transitions }, vibrations=MarcusModel(transitions=transitions)), DecayRate(initial_state=s1, final_state=gs, decay_rate_function=decay_rate, description='custom decay rate') ] self.system.cutoff_radius = 10.0 # interaction cutoff radius in Angstrom # some system analyze functions system_test_info(self.system) trajectories = calculate_kmc( self.system, num_trajectories=10, # number of trajectories that will be simulated max_steps=10000, # maximum number of steps for trajectory allowed silent=True) # Results analysis analysis = TrajectoryAnalysis(trajectories) print('diffusion coefficient: {:9.5f} Angs^2/ns'.format( analysis.diffusion_coefficient('s1'))) print('lifetime: {:9.5f} ns'.format( analysis.lifetime('s1'))) print('diffusion length: {:9.5f} Angs'.format( analysis.diffusion_length('s1'))) print('diffusion tensor (Angs^2/ns)') print(analysis.diffusion_coeff_tensor('s1')) print('diffusion length square tensor (Angs)') print(analysis.diffusion_length_square_tensor('s1')) test = { 'diffusion coefficient': np.around(analysis.diffusion_coefficient('s1'), decimals=4), 'lifetime': np.around(analysis.lifetime('s1'), decimals=4), 'diffusion length': np.around(analysis.diffusion_length('s1'), decimals=4), 'diffusion tensor': np.around(analysis.diffusion_coeff_tensor('s1'), decimals=4).tolist(), 'diffusion length tensor': np.around(np.sqrt(analysis.diffusion_length_square_tensor('s1')), decimals=6).tolist() } print(test) ref = { 'diffusion coefficient': 0.4265, 'lifetime': 24.1692, 'diffusion length': 5.4498, 'diffusion tensor': [[0.4265]], 'diffusion length tensor': [[5.449771]] } self.assertDictEqual(ref, test)