def setUp(self): np.random.seed( 0 ) # set random seed in order for the examples to reproduce the exact references # setup molecules molecule = Molecule() molecule1 = molecule.copy() molecule1.set_coordinates([0]) molecule1.name = 'TypeA' molecule2 = molecule.copy() molecule2.set_coordinates([1]) molecule2.name = 'TypeB' molecule3 = molecule.copy() molecule3.set_coordinates([2]) molecule3.name = 'TypeC' # setup system self.system = System(molecules=[molecule1, molecule2, molecule3], supercell=[[3]]) # set initial exciton # self.system.add_excitation_index(tt, 1) # self.system.add_excitation_random(s1, 2) self.system.add_excitation_index(s1, 0) self.system.add_excitation_index(s1, 1)
def regular_system(molecule, lattice=None, orientation=None, ): if lattice is None: lattice = {'size': [1], 'parameters': [1.0]} # default 1D 1 molecule system molecules = [] # list of instances of class molecule for subset in itertools.product(*[list(range(n)) for n in lattice['size']]): coordinates = np.multiply(subset, lattice['parameters']) final_orientation = list(orientation) for j in range(3): if final_orientation[j] is None: final_orientation[j] = np.random.random_sample() * 2 * np.pi molecule = molecule.copy() # copy of the generic instance molecule.set_coordinates(coordinates) molecule.set_orientation(final_orientation) molecules.append(molecule) supercell = np.diag(np.multiply(lattice['size'], lattice['parameters'])) return System(molecules, supercell)
def setUp(self): # setup molecules molecule = Molecule() molecule1 = molecule.copy() molecule1.set_coordinates([0]) molecule1.name = 'TypeA' molecule2 = molecule.copy() molecule2.set_coordinates([1]) molecule2.name = 'TypeB' molecule3 = molecule.copy() molecule3.set_coordinates([2]) molecule3.name = 'TypeC' # setup system self.system = System(molecules=[molecule1, molecule2, molecule3], supercell=[[3]]) # set initial exciton self.system.add_excitation_index(s1, 1) self.system.add_excitation_index(s1, 0)
def crystal_system(molecules, scaled_site_coordinates, dimensions=None, unitcell=None, orientations=None, ): unitcell = np.array(unitcell) scaled_site_coordinates = np.array(scaled_site_coordinates) n_mol, n_dim = scaled_site_coordinates.shape if dimensions is None: dimensions = [1] * n_dim if orientations is None: orientations = [None for _ in range(n_mol)] molecules_list = [] # list of instances of class molecule for i, (coordinate, molecule_type) in enumerate(zip(scaled_site_coordinates, molecules)): for subset in itertools.product(*[list(range(n)) for n in dimensions]): r_cell = np.sum([s * lattice_vector for s, lattice_vector in zip(subset, unitcell)], axis=0) coor = r_cell + np.dot(unitcell.T, coordinate) molecule = molecule_type.copy() # copy of the generic instance molecule.set_coordinates(coor) molecule.name = 'a{}'.format(i+1) final_orientation = list(orientations[i]) for j in range(3): if final_orientation[j] is None: final_orientation[j] = np.random.random_sample() * 2 * np.pi else: final_orientation[j] = final_orientation[j] molecule.set_orientation(final_orientation) molecules_list.append(molecule) supercell = np.dot(unitcell.T, np.diag(dimensions)).T return System(molecules_list, supercell)
class Test1DFast(unittest.TestCase): def setUp(self): # setup molecules molecule = Molecule() molecule1 = molecule.copy() molecule1.set_coordinates([0]) molecule1.name = 'TypeA' molecule2 = molecule.copy() molecule2.set_coordinates([1]) molecule2.name = 'TypeB' molecule3 = molecule.copy() molecule3.set_coordinates([2]) molecule3.name = 'TypeC' # setup system self.system = System(molecules=[molecule1, molecule2, molecule3], supercell=[[3]]) # set initial exciton self.system.add_excitation_index(s1, 1) self.system.add_excitation_index(s1, 0) def test_kmc_algorithm(self): np.random.seed( 0 ) # set random seed in order for the examples to reproduce the exact references # set additional system parameters self.system.process_scheme = [ DirectRate(initial_states=(s1, gs), final_states=(gs, s1), rate_constant_function=transfer_rate, arguments={'custom_constant': 1}, description='transport s1'), DirectRate(initial_states=(s1, s1), final_states=(tt, ), rate_constant_function=transfer_rate, arguments={'custom_constant': 1}, description='merge s1-s1 -> tt'), DirectRate(initial_states=(tt, ), final_states=(gs, gs), rate_constant_function=decay_rate, description='decay tt'), DirectRate(initial_states=(tt, gs), final_states=(gs, tt), rate_constant_function=decay_rate, description='transport tt') ] self.system.cutoff_radius = 10.0 # interaction cutoff radius in Angstrom p = DirectRate(initial_states=(s1, s1), final_states=(tt, ), rate_constant_function=transfer_rate, arguments={'custom_constant': 1}, description='custom2') #print(p.get_transition_connections()) #exit() # 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=50, # 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('tt'))) print('lifetime: {:9.5f} ns'.format( analysis.lifetime('tt'))) print('diffusion length: {:9.5f} Angs'.format( analysis.diffusion_length('tt'))) print('diffusion tensor (Angs^2/ns)') print(analysis.diffusion_coeff_tensor('tt')) print('diffusion length square tensor (Angs)') print(analysis.diffusion_length_square_tensor('tt')) test = { 'diffusion coefficient': np.around(analysis.diffusion_coefficient('tt'), decimals=4), 'lifetime': np.around(analysis.lifetime('tt'), decimals=4), 'diffusion length': np.around(analysis.diffusion_length('tt'), decimals=4), 'diffusion tensor': np.around(analysis.diffusion_coeff_tensor('tt'), decimals=4).tolist(), 'diffusion length tensor': np.around(np.sqrt(analysis.diffusion_length_square_tensor('tt')), decimals=4).tolist() } ref = { 'diffusion coefficient': 0.4819, 'lifetime': 28.3726, 'diffusion length': 4.1018, 'diffusion tensor': [[0.4819]], 'diffusion length tensor': [[4.1018]] } self.assertDictEqual(ref, test)
class Test1DFast(unittest.TestCase): def setUp(self): # setup molecules molecule = Molecule() molecule1 = molecule.copy() molecule1.set_coordinates([0]) molecule1.name = 'TypeA' molecule2 = molecule.copy() molecule2.set_coordinates([1]) molecule2.name = 'TypeB' molecule3 = molecule.copy() molecule3.set_coordinates([2]) molecule3.name = 'TypeC' # setup system self.system = System(molecules=[molecule1, molecule2, molecule3], supercell=[[3]]) # set initial exciton self.system.add_excitation_index(s2, 1) self.system.add_excitation_index(s1, 2) def test_kmc_algorithm(self): np.random.seed( 0 ) # set random seed in order for the examples to reproduce the exact references # set additional system parameters self.system.process_scheme = [ DirectRate(initial_states=(s1, gs), final_states=(gs, s1), rate_constant_function=transfer_rate, arguments={'custom_constant': 1}, description='transport'), DirectRate(initial_states=(s1, ), final_states=(gs, ), rate_constant_function=decay_rate, description='custom decay rate'), DirectRate(initial_states=(s2, s2), final_states=(gs, s1), rate_constant_function=decay_rate, description='merge'), DirectRate(initial_states=(s1, gs), final_states=(s2, s2), rate_constant_function=decay_rate, description='split'), DirectRate(initial_states=(s2, gs), final_states=(gs, s2), rate_constant_function=transfer_rate, arguments={'custom_constant': 1}, description='transport 2'), DirectRate(initial_states=(s2, ), final_states=(gs, ), rate_constant_function=decay_rate, description='custom decay rate 2'), ] #print([s.label for s in self.system.decay_scheme[0].initial], '--', # [s.label for s in self.system.decay_scheme[0].final]) #print([s.label for s in self.system.decay_scheme[1].initial], '--', # [s.label for s in self.system.decay_scheme[1].final]) 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=50, # number of trajectories that will be simulated max_steps=18, # maximum number of steps for trajectory allowed silent=True) # Results analysis analysis = TrajectoryAnalysis(trajectories) for traj in trajectories: print('diff:', traj.get_diffusion('s1')) print('diff none:', traj.get_diffusion(None)) #print('path:', traj._trajectory_node_path()) #print('path:', trajectories[0]._trajectory_node_path_new()) #print('-> diff:', trajectories[8].get_diffusion('s1')) #print('-> diff none:', trajectories[8].get_diffusion(None)) #print('path:', trajectories[8]._trajectory_node_path()) #trajectories[0].plot_graph().show() #exit() 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=4).tolist() } print(test) ref = { 'diffusion coefficient': 3.5571, 'lifetime': 2.2493, 'diffusion length': 3.9478, 'diffusion tensor': [[3.5571]], 'diffusion length tensor': [[3.9478]] } self.assertDictEqual(ref, test) 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)
molecule = Molecule() molecule1 = molecule.copy() molecule1.set_coordinates([0]) molecule1.name = 'TypeA' molecule2 = molecule.copy() molecule2.set_coordinates([1]) molecule2.name = 'TypeB' molecule3 = molecule.copy() molecule3.set_coordinates([2]) molecule3.name = 'TypeC' # setup system system = System(molecules=[molecule1, molecule2, molecule3], supercell=[[3]]) # set initial exciton system.add_excitation_index(s1, 1) system.add_excitation_index(s2, 2) # set additional system parameters system.process_scheme = [ DirectRate(initial_states=(s1, gs), final_states=(gs, s1), rate_constant_function=transfer_rate, description='custom'), DirectRate(initial_states=(s2, gs), final_states=(gs, s2), rate_constant_function=transfer_rate, description='custom'),