def change_cell_length(atoms, space_group): #print(atoms.get_positions()) #print(atoms.get_atomic_numbers()) name = get_name(atoms.get_atomic_numbers()) #print(name) molecule1, molecule2, molecule3, molecule4 = molecule_lists(atoms)[0], molecule_lists(atoms)[1], molecule_lists(atoms)[2], molecule_lists(atoms)[3] # [1,5,9,13,17,21,etc] #print("molecule1: ", molecule1) #print(molecule2) #print(molecule3) #print(molecule4) scaled_positions = atoms.get_scaled_positions() molecule1_scaled_positions = np.array([scaled_positions[i] for i in molecule1]) #print("molecule1_scaled_positions: ", molecule1_scaled_positions) molecule2_scaled_positions = np.array([scaled_positions[i] for i in molecule2]) molecule3_scaled_positions = np.array([scaled_positions[i] for i in molecule3]) molecule4_scaled_positions = np.array([scaled_positions[i] for i in molecule4]) cell_params = atoms.get_cell() #print(atoms.get_cell()) a_vector, b_vector, c_vector = cell_params[0], cell_params[1], cell_params[2] molecule1_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule1_scaled_positions]) #print("molecule1_vectors: ", molecule1_vectors) molecule2_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule2_scaled_positions]) molecule3_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule3_scaled_positions]) molecule4_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule4_scaled_positions]) new_atoms = atoms.copy() new_atoms.set_cell(cell_params + np.array([[3.0, 0, 0],[0, 3.0, 0],[0.0, 0, 3.0]]), scale_atoms=True) new_cell_params = new_atoms.get_cell() print("first atoms: ", new_atoms.get_positions()[0]) #print("new_cell_params: ", new_cell_params) new_a_vector, new_b_vector, new_c_vector = new_cell_params[0], new_cell_params[1], new_cell_params[2] new_scaled_positions_molecule1 = get_position_for_molecule(molecule1_vectors, new_a_vector, new_b_vector, new_c_vector) #print("new_scaled_positions_molecule1: ", new_scaled_positions_molecule1) new_scaled_positions_molecule2 = get_position_for_molecule(molecule2_vectors, new_a_vector, new_b_vector, new_c_vector) new_scaled_positions_molecule3 = get_position_for_molecule(molecule3_vectors, new_a_vector, new_b_vector, new_c_vector) new_scaled_positions_molecule4 = get_position_for_molecule(molecule4_vectors, new_a_vector, new_b_vector, new_c_vector) #print("get_symop(): ", space_group.get_symop()) sites = [] for r1, r2, r3, r4 in zip(new_scaled_positions_molecule1, new_scaled_positions_molecule2, new_scaled_positions_molecule3, new_scaled_positions_molecule4): sites.append(r1) sites.append(r2) sites.append(r3) sites.append(r4) new_positions = np.array([faction[0] * new_a_vector + faction[1] * new_b_vector + faction[2] * new_c_vector for faction in sites]) #print(new_positions - atoms.get_positions()) #print(new_positions) writer = Atoms(name, positions=new_positions, cell=new_atoms.get_cell(), pbc=[1,1,1]) #for i in molecule3: # print(writer.get_distances(i, molecule3) - atoms.get_distances(i, molecule3)) #print(writer.get_cell()) return writer
def rigid_body_movement(atoms): ret_molecule_lists = molecule_lists(atoms) x_com = get_com(atoms, ret_molecule_lists) print("x_com: ", x_com) F = np.matrix([[1,0,0],[0,1,0],[0,0,1]]) delta_a, delta_b, delta_c = random_draw(0.1,0.1), random_draw(0.1,0.1), random_draw(0.1,0.1) new_F = F + np.matrix([[delta_a, 0, 0],[0, delta_b, 0],[0, 0, delta_c]]) X = atoms.get_positions() x_com_new = np.matmul(x_com, new_F) L = atoms.get_cell() L_new = np.matmul(L, new_F) atoms.set_cell(L_new, scale_atoms=False) #imolec, molec: 0 [1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81] #imolec, molec: 1 [2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62, 66, 70, 74, 78, 82] #imolec, molec: 2 [3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, 71, 75, 79, 83] #imolec, molec: 3 [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84] for imolec, molec in enumerate(ret_molecule_lists): print("imolec, molec: ", imolec, molec) for j in molec: for i in [0, 1, 2]: X[j-1, i] += (x_com_new[imolec, i] - x_com[imolec, i]) #X[j-1, i] += x_com_new[imolec, i] atoms.set_positions(X) return atoms
def generate_cell_length_c_frame(atoms, molecule1_atoms_index, space_group, sigma=0.1): name = get_name(atoms.get_atomic_numbers()) st = ase_atoms_to_structure(atoms) my_atoms = atoms.copy() my_atoms.set_positions(st.getXYZ()) molecules = molecule_lists(my_atoms) old_positions = my_atoms.get_positions() molecule1_vectors = np.array([old_positions[i] for i in molecules[0]]) # set the perturbation new_atoms = my_atoms.copy() a, b, c, alpha, beta, gamma = my_atoms.get_cell_lengths_and_angles() if a != b and b != c and c != a: new_a, new_b, new_c = a, b, c + random_draw(sigma) elif a != b and b == c: new_a, new_c = a, c + random_draw(sigma) new_b = new_c elif a != b and a == c: new_c, new_b = c + random_draw(sigma), b new_a = new_c elif a == b and a != c: new_b, new_c = b, c + random_draw(sigma) new_a = new_b else: new_c = c + random_draw(sigma) new_a = new_c new_b = new_c # scaled_atoms = True new_atoms.set_cell([new_a, new_b, new_c, alpha, beta, gamma], scale_atoms=True) new_cell_params = new_atoms.get_cell() new_a_vector, new_b_vector, new_c_vector = new_cell_params[ 0], new_cell_params[1], new_cell_params[2] new_molecule1_vectors = get_xyz_after_move(my_atoms.get_positions()[0], new_atoms.get_positions()[0], molecule1_vectors) sites = [] for pos in new_molecule1_vectors: for rot, trans in space_group.get_symop(): trans_a, trans_b, trans_c = trans[:] site = np.dot( rot, pos ) + trans_a * new_a_vector + trans_b * new_b_vector + trans_c * new_c_vector sites.append(site) new_positions = np.array(sites) ret_atoms = Atoms(name, positions=new_positions, cell=new_atoms.get_cell(), pbc=[1, 1, 1]) return ret_atoms
def move_molecule1(atoms, space_group): print("atoms.get_distance(1,5): ", atoms.get_distance(1, 5, mic=False, vector=True)) print("atoms.get_distance(1,21): ", atoms.get_distance(1, 21, mic=False, vector=True)) a, b, c, alpha, beta, gamma = atoms.get_cell_lengths_and_angles() X = atoms.get_positions() old_scaled_position = atoms.get_scaled_positions() print("a, b, c, alpha, beta, gamma: ", a, b, c, alpha, beta, gamma) #print("X: ", X) #print("old_scaled_position: ", old_scaled_position) molecule1 = molecule_lists(atoms)[0] st = ase_atoms_to_structure(atoms) x_com1 = center_of_mass(st, molecule1) X_molecule1 = np.array([X[x - 1] for x in molecule1]) #print("X_molecule1: ", X_molecule1) F = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) delta_a, delta_b, delta_c = random_draw(0.1, 0.1), random_draw( 0.1, 0.1), random_draw(0.1, 0.1) new_F = F + np.array([[delta_a, 0, 0], [0, delta_b, 0], [0, 0, delta_c]]) x_com1_new = np.dot(x_com1, new_F) diff_com = x_com1_new - x_com1 #print("diff_com: ", diff_com) new_X = [] for i, row in enumerate(X): if i + 1 in molecule1: new_X.append(row + diff_com) else: new_X.append(row) L = atoms.get_cell() new_L = np.dot(L, new_F) new_atoms = atoms.copy() new_atoms.set_positions(new_X) new_atoms.set_cell(new_L, scale_atoms=False) scaled_positions = new_atoms.get_scaled_positions() molecule1_scaled_positions = [scaled_positions[i - 1] for i in molecule1] final_scaled_positions = get_equivalent_sites(molecule1_scaled_positions, space_group) #print("final_scaled_positions: ", final_scaled_positions) new_atoms.set_scaled_positions(final_scaled_positions) print("new_atoms.get_distance(1,5): ", new_atoms.get_distance(1, 5, mic=False, vector=True)) print("new_atoms.get_distance(1,21): ", new_atoms.get_distance(1, 21, mic=False, vector=True)) return new_atoms
def generate_perturb(atoms): atoms_input = atoms.copy() ret_atoms_cell_length = generate_cell_length_frame(atoms_input, molecule1_atoms_index, space_group, 2.0) print("after cell length ", molecule_lists(ret_atoms_cell_length)) ret_atoms_cell_angle = generate_cell_angle_frame(ret_atoms_cell_length, molecule1_atoms_index, space_group, 0.1) print("after cell angle ", molecule_lists(ret_atoms_cell_angle)) ret_atoms_rotation = generate_rotation_frame(ret_atoms_cell_angle, molecule1_atoms_index, space_group, 0.1) print("after rotation ", molecule_lists(ret_atoms_rotation)) ret_atoms_translate = generate_translate_frame(ret_atoms_rotation, molecule1_atoms_index, space_group, 0.1) print("after translation ", molecule_lists(ret_atoms_translate)) ret_atoms = ret_atoms_translate.copy() return ret_atoms
def generate_perturb(atoms_input): """ For debug use """ ret_atoms_cell_length_a = generate_cell_length_a_frame( atoms_input, molecule1_atoms_index, space_group, 10.0) print("after cell length a", molecule_lists(ret_atoms_cell_length_a)) ret_atoms_cell_length_b = generate_cell_length_b_frame( ret_atoms_cell_length_a, molecule1_atoms_index, space_group, 10.0) print("after cell length b", molecule_lists(ret_atoms_cell_length_b)) ret_atoms_cell_length_c = generate_cell_length_c_frame( ret_atoms_cell_length_b, molecule1_atoms_index, space_group, 10.0) print("after cell length b", molecule_lists(ret_atoms_cell_length_c)) ret_atoms_cell_angle_beta = generate_cell_angle_beta_frame( ret_atoms_cell_length_c, molecule1_atoms_index, space_group, 5.0) print("after cell angle ", molecule_lists(ret_atoms_cell_angle_beta)) ret_atoms_rotation = generate_rotation_frame(ret_atoms_cell_angle_beta, molecule1_atoms_index, space_group, 10.0) print("after rotation ", molecule_lists(ret_atoms_rotation)) ret_atoms_translate = generate_translate_frame(ret_atoms_rotation, molecule1_atoms_index, space_group, 2.0) print("after translation ", molecule_lists(ret_atoms_translate)) ret_atoms = ret_atoms_translate.copy() return ret_atoms
def change_cell_length(atoms, space_group): name = get_name(atoms.get_atomic_numbers()) molecule1, molecule2, molecule3, molecule4 = molecule_lists(atoms)[0], molecule_lists(atoms)[1], molecule_lists(atoms)[2], molecule_lists(atoms)[3] # [1,5,9,13,17,21,etc] scaled_positions = atoms.get_scaled_positions() molecule1_scaled_positions = np.array([scaled_positions[i] for i in molecule1]) molecule2_scaled_positions = np.array([scaled_positions[i] for i in molecule2]) molecule3_scaled_positions = np.array([scaled_positions[i] for i in molecule3]) molecule4_scaled_positions = np.array([scaled_positions[i] for i in molecule4]) cell_params = atoms.get_cell() a_vector, b_vector, c_vector = cell_params[0], cell_params[1], cell_params[2] molecule1_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule1_scaled_positions]) molecule2_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule2_scaled_positions]) molecule3_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule3_scaled_positions]) molecule4_vectors = np.array([faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule4_scaled_positions]) new_atoms = atoms.copy() new_atoms.set_cell(cell_params + np.array([[3.0, 0, 0],[0, 3.0, 0],[0.0, 0, 3.0]]), scale_atoms=False) new_cell_params = new_atoms.get_cell() new_a_vector, new_b_vector, new_c_vector = new_cell_params[0], new_cell_params[1], new_cell_params[2] new_scaled_positions_molecule1 = get_position_for_molecule(molecule1_vectors, new_a_vector, new_b_vector, new_c_vector) print("new_scaled_positions_molecule1: ", new_scaled_positions_molecule1) exit()
def generate_cell_angle_frame(atoms, molecule1_atoms_index, space_group, mu=0.1, sigma=0.1): # get names and molecule idx name = get_name(atoms.get_atomic_numbers()) st = ase_atoms_to_structure(atoms) my_atoms = atoms.copy() my_atoms.set_positions(st.getXYZ()) molecules = molecule_lists(my_atoms) old_positions = my_atoms.get_positions() molecule1_vectors = np.array([old_positions[i] for i in molecules[0]]) # set the perturbation new_atoms = my_atoms.copy() a, b, c, alpha, beta, gamma = my_atoms.get_cell_lengths_and_angles() new_cell_params = [a, b, c] for angle in [alpha, beta, gamma]: if angle != 90: new_cell_params.append(angle + random_draw(mu, sigma)) else: new_cell_params.append(angle) new_atoms.set_cell(new_cell_params, scale_atoms=True) new_cell_params = new_atoms.get_cell() new_a_vector, new_b_vector, new_c_vector = new_cell_params[ 0], new_cell_params[1], new_cell_params[2] new_molecule1_vectors = get_xyz_after_move(my_atoms.get_positions()[0], new_atoms.get_positions()[0], molecule1_vectors) sites = [] for pos in new_molecule1_vectors: for rot, trans in space_group.get_symop(): trans_a, trans_b, trans_c = trans[:] site = np.dot( rot, pos ) + trans_a * new_a_vector + trans_b * new_b_vector + trans_c * new_c_vector sites.append(site) new_positions = np.array(sites) ret_atoms = Atoms(name, positions=new_positions, cell=new_atoms.get_cell(), pbc=[1, 1, 1]) return ret_atoms
def rigid_body_movement(atoms): ret_molecule_lists = molecule_lists(atoms) molecule1 = ret_molecule_lists[0] atom1_index = molecule1[0] scaled_position = atoms.get_scaled_positions(wrap=True) print("atom1_index: ", atom1_index) # print("atoms scaled position: ", scaled_position) print("atoms1 scaled position: ", scaled_position[atom1_index - 1]) atom2_index = molecule1[1] print("atoms2 scaled position: ", scaled_position[atom2_index - 1]) a, b, c, alpha, beta, gamma = atoms.get_cell_lengths_and_angles() return atoms
def Monte_Carlo(atoms, calculator, space_group, step_size, perturbation, counter, molecule1_in_cell=[], MC_steps=1000, debug=False): """ atoms: atoms class in ASE module perturbation: str represent cell and xyz changes counter: int for writing files return a new frame base on: if new_E < old_E: accepted, continue MD with new frame elif new_E > old_E: delta_Emn = new_E - old_E p = exp(-delta_Emn/kBT) generate a random number nu(0,1) if p > nu: accepted, continue MD with new frame else: rejected, continue MD with old frame """ a, b, c, alpha, beta, gamma = atoms.get_cell_lengths_and_angles() xyz = atoms.get_positions() fraction = atoms.get_scaled_positions() MC_trace[counter] = {} MC_trace[counter]['a'] = a MC_trace[counter]['b'] = b MC_trace[counter]['c'] = c MC_trace[counter]['alpha'] = alpha MC_trace[counter]['beta'] = beta MC_trace[counter]['gamma'] = gamma MC_trace[counter]['xyz'] = xyz.tolist() MC_trace[counter]['fraction'] = fraction.tolist() old_atoms = atoms.copy() old_atoms.set_calculator(calculator) old_E = atoms.get_total_energy() if perturbation == "translate": new_atoms = generate_translate_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "rotation": new_atoms = generate_rotation_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_length": new_atoms = generate_cell_length_frame(atoms, molecule1_in_cell, space_group, step_size) else: new_atoms = generate_cell_angle_frame(atoms, molecule1_in_cell, space_group, step_size) if (len(molecule_lists(new_atoms)) != len(molecule_lists(old_atoms))): print("%s move by %f to Frame %d Rejected due to clash!" % (perturbation, step_size, counter)) outfile = "Rejected_clash_%d.cif" % counter ase_io.write(outfile, new_atoms) return old_atoms, "Rejected" new_atoms.set_calculator(calculator) new_E = new_atoms.get_total_energy() #print("old_E and new_E: ", old_E, new_E) if new_E < old_E: print("Frame %d Accepted!" % counter) if counter % 100 == 0 or MC_steps - counter < 100 or debug: outfile = "Accepted_%d.cif" % counter ase_io.write(outfile, new_atoms) return new_atoms, "Accepted" else: delta_Emn = new_E - old_E delta_Emn = delta_Emn * 23 # ev to kcal/mol p = math.exp(-delta_Emn / units.kB / 300) nu = random.uniform(0, 1) if p > nu: print("Frame %d Accepted!" % counter) if counter % 100 == 0 or MC_steps - counter < 100 or debug: outfile = "Accepted_%d.cif" % counter ase_io.write(outfile, new_atoms) return new_atoms, "Accepted" else: print("Frame %d Rejected!" % counter) return old_atoms, "Rejected"
ret_atoms_translate = generate_translate_frame(ret_atoms_rotation, molecule1_atoms_index, space_group, 2.0) print("after translation ", molecule_lists(ret_atoms_translate)) ret_atoms = ret_atoms_translate.copy() return ret_atoms if __name__ == "__main__": print("runing main function for debugging...") atoms = ase_io.read(sys.argv[1]) spacegroup_number = sys.argv[2] molecule1_atoms_index = molecule_lists(atoms)[0] print(molecule_lists(atoms)) print("molecule1_atoms_index: ", molecule1_atoms_index) if spacegroup_number: space_group = Spacegroup(int(spacegroup_number)) else: space_group = spacegroup.get_spacegroup(atoms) print("before perturbation: ", space_group) # first enlarge cell and then change the anlge. #ret_atoms = ret_atoms_translate.copy() # atoms_input = atoms.copy() # ret_atoms = generate_perturb(atoms_input) # dummy input ret_atoms = Atoms('Au', positions=[[0, 10 / 2, 10 / 2]], cell=[10, 10, 10],
def main(): args = parse_args() print("args", args) if args.implementation == TORCHANI: from torchani_calculator import torchani_calculator calculator = torchani_calculator(args.network_type) elif args.implementation == AES_ANI: from ani_ase import ani_ase_calculator calculator = ani_ase_calculator(args.network_type) elif args.implementation == KHAN: from khan_calculator import khan_calculator calculator = khan_calculator(args.network_type, args.khan_network, args.numb_networks) assert args.cif_file.endswith('.cif') print('debug? ', args.debug) atoms = ase_io.read(args.cif_file) numb_molecules = len(molecule_lists(atoms)) print('number of molecules: ', numb_molecules) MC_stpes = args.MC space_group = Spacegroup(args.space_group) # step size in MC f1, f2, f3, f4, f5, f6, f7, f8 = args.MC_f1_f2_f3_f4_f5_f6_f7_f8 perturbation_type = args.perturbation_type molecule1_in_cell = [] for i in range(1, atoms.get_number_of_atoms()): if atom_belong_to_mol1(i, atoms): molecule1_in_cell.append(i) print("initial unit cell") print(atoms.cell) print("To do Monte Carlo for %d step." % MC_stpes) print("Molecule index in ASU are: ", molecule1_in_cell) translation_stats = [] rotation_stats = [] cell_length_a_stats = [] cell_length_b_stats = [] cell_length_c_stats = [] cell_angle_alpha_stats = [] cell_angle_beta_stats = [] cell_angle_gamma_stats = [] counter = 0 atoms_input = atoms.copy() while (counter <= MC_stpes): if isinstance(perturbation_type, list): # random_number = random.choice([1,2,3,4,5,6,7,8]) random_choices = get_random_choices( [f1, f2, f3, f4, f5, f6, f7, f8]) random_number = random.choice(random_choices) else: random_number = perturbation_dict[perturbation_type] if random_number == 1: # translation atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f1, 'translate', counter, molecule1_in_cell, MC_stpes, args.debug) translation_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 2: # rotation atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f2, 'rotation', counter, molecule1_in_cell, MC_stpes, args.debug) rotation_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 3: # cell_length a atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f3, 'cell_length_a', counter, molecule1_in_cell, MC_stpes, args.debug) cell_length_a_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 4: # cell_length b atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f4, 'cell_length_b', counter, molecule1_in_cell, MC_stpes, args.debug) cell_length_b_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 5: # cell_length c atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f5, 'cell_length_c', counter, molecule1_in_cell, MC_stpes, args.debug) cell_length_c_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 6: # cell_angle alpha atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f6, 'cell_angle_alpha', counter, molecule1_in_cell, MC_stpes, args.debug) cell_angle_alpha_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 7: # cell_angle beta atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f7, 'cell_angle_beta', counter, molecule1_in_cell, MC_stpes, args.debug) cell_angle_beta_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 8: # cell_angle gamma atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f8, 'cell_angle_gamma', counter, molecule1_in_cell, MC_stpes, args.debug) cell_angle_gamma_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() #if counter % 1000 == 0: # with open("MC_trace_%d.json"%counter, "w") as fh: # json.dump(MC_trace, fh, indent=4) #with open("MC_trace.json", "w") as fh: # json.dump(MC_trace, fh, indent=4) #print("MC trace are recorded in: MC_trace.json") if len(translation_stats): print("Acceptance ratio of translation move is %f" % (countX("Accepted", translation_stats) / len(translation_stats))) if len(rotation_stats): print("Acceptance ratio of rotation move is %f" % (countX("Accepted", rotation_stats) / len(rotation_stats))) if len(cell_length_a_stats): print("Acceptance ratio of cell length a move is %f" % (countX("Accepted", cell_length_a_stats) / len(cell_length_a_stats))) if len(cell_length_b_stats): print("Acceptance ratio of cell length b move is %f" % (countX("Accepted", cell_length_b_stats) / len(cell_length_b_stats))) if len(cell_length_c_stats): print("Acceptance ratio of cell length c move is %f" % (countX("Accepted", cell_length_c_stats) / len(cell_length_c_stats))) if len(cell_angle_alpha_stats): print("Acceptance ratio of cell angle alpha move is %f" % (countX("Accepted", cell_angle_alpha_stats) / len(cell_angle_alpha_stats))) if len(cell_angle_beta_stats): print("Acceptance ratio of cell angle beta move is %f" % (countX("Accepted", cell_angle_beta_stats) / len(cell_angle_beta_stats))) if len(cell_angle_gamma_stats): print("Acceptance ratio of cell angle gamma move is %f" % (countX("Accepted", cell_angle_gamma_stats) / len(cell_angle_gamma_stats)))
def Monte_Carlo(atoms, calculator, space_group, step_size, perturbation, counter, molecule1_in_cell=[], MC_steps=1000, debug=False): """ A Monte_Carlo function that takes in an atoms instance and generate a new atoms instance base on metropolis monte carlo :type atoms: Atoms.atoms :param atoms: ASE atoms instance which contains a collection of atoms and their related information :type calculator: ase.calculator :param calculator: ANI calculator which is used to get force and energy base on atomic numbers and positions :type space_group: ase.spacegroup.Spacegroup :param space_group: the space group that MC is performing under :type step_size: array :param step_size: step size for T, R, cell_a, cell_b, cell_c, cell_alpha, cell_beta, cell_gamma :type perturbation: str :param perturbation: the type of perturbation that MC is performing under :type counter: int :param counter: the number of MC steps :type molecule1_in_cell: array :param molecule1_in_cell: atom indexs for the asymmetric molecule in cell :type MC_steps: int :param MC_steps: the number of MC steps that will be performed :type debug: bool :param debug: show debug information including all accepted and rejected moves return a new frame base on metropolis monte carlo shown as below: if new_E < old_E: accepted, continue MD with new frame elif new_E > old_E: delta_Emn = new_E - old_E p = exp(-delta_Emn/kBT) generate a random number nu(0,1) if p > nu: accepted, continue MD with new frame else: rejected, continue MD with old frame """ a, b, c, alpha, beta, gamma = atoms.get_cell_lengths_and_angles() xyz = atoms.get_positions() fraction = atoms.get_scaled_positions() #MC_trace[counter] = {} #MC_trace[counter]['a'] = a #MC_trace[counter]['b'] = b #MC_trace[counter]['c'] = c #MC_trace[counter]['alpha'] = alpha #MC_trace[counter]['beta'] = beta #MC_trace[counter]['gamma'] = gamma #MC_trace[counter]['xyz'] = xyz.tolist() #MC_trace[counter]['fraction'] = fraction.tolist() #MC_trace[counter]['density'] = len(atoms)/atoms.get_volume() old_atoms = atoms.copy() old_atoms.set_calculator(calculator) old_E = old_atoms.get_total_energy() #MC_trace[counter]['Energy'] = old_E try: if perturbation == "translate": new_atoms = generate_translate_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "rotation": new_atoms = generate_rotation_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_length_a": new_atoms = generate_cell_length_a_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_length_b": new_atoms = generate_cell_length_b_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_length_c": new_atoms = generate_cell_length_c_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_angle_alpha": new_atoms = generate_cell_angle_alpha_frame( atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_angle_beta": new_atoms = generate_cell_angle_beta_frame(atoms, molecule1_in_cell, space_group, step_size) elif perturbation == "cell_angle_gamma": new_atoms = generate_cell_angle_gamma_frame( atoms, molecule1_in_cell, space_group, step_size) if (len(molecule_lists(new_atoms)) != len(molecule_lists(old_atoms))): print("%s move by %f to Frame %d Rejected due to clash!" % (perturbation, step_size, counter)) outfile = "Rejected_clash_%d.cif" % counter ase_io.write(outfile, new_atoms) return old_atoms, "Rejected" except: print("failed during generation of frame %d by doing %s change" % (counter, perturbation)) outfile = "Failed_frame_%d.cif" % counter ase_io.write(outfile, old_atoms) return old_atoms, "Rejected" new_atoms.set_calculator(calculator) new_E = new_atoms.get_total_energy() if new_E < old_E: print("Frame %d Accepted!" % counter) if counter % 100 == 0 or MC_steps - counter < 100 or debug: outfile = "Accepted_%d.cif" % counter ase_io.write(outfile, new_atoms) return new_atoms, "Accepted" else: delta_Emn = new_E - old_E delta_Emn = delta_Emn * 23 # ev to kcal/mol p = math.exp(-delta_Emn / units.kB / 300) nu = random.uniform(0, 1) if p > nu: print("Frame %d Accepted!" % counter) if counter % 100 == 0 or MC_steps - counter < 100 or debug: outfile = "Accepted_%d.cif" % counter ase_io.write(outfile, new_atoms) return new_atoms, "Accepted" else: print("Frame %d Rejected!" % counter) return old_atoms, "Rejected"
def main(): args = parse_args() print("args", args) if args.implementation == TORCHANI: from torchani_calculator import torchani_calculator calculator = torchani_calculator(args.network_type) elif args.implementation == AES_ANI: from ani_ase import ani_ase_calculator calculator = ani_ase_calculator(args.network_type) elif args.implementation == KHAN: from khan_calculator import khan_calculator calculator = khan_calculator(args.network_type, args.khan_network, args.numb_networks) assert args.cif_file.endswith('.cif') print('debug? ', args.debug) atoms = ase_io.read(args.cif_file) numb_molecules = len(molecule_lists(atoms)) print('number of molecules: ', numb_molecules) MC_stpes = args.MC space_group = Spacegroup(args.space_group) # step size in MC f1, f2, f3, f4, f5, f6, f7, f8 = args.MC_f1_f2_f3_f4_f5_f6_f7_f8 perturbation_type = args.perturbation_type molecule1_in_cell = [] for i in range(1, atoms.get_number_of_atoms()): if atom_belong_to_mol1(i, atoms): molecule1_in_cell.append(i) print("initial unit cell") print(atoms.cell) print("To do Monte Carlo for %d step." % MC_stpes) print("Molecule index in ASU are: ", molecule1_in_cell) counter = 0 atoms.set_calculator(calculator) while (counter <= MC_stpes): if isinstance(perturbation_type, list): # random_number = random.choice([1,2,3,4,5,6,7,8]) random_choices = get_random_choices( [f1, f2, f3, f4, f5, f6, f7, f8]) random_number = random.choice(random_choices) else: random_number = perturbation_dict[perturbation_type] if random_number == 1: # translation Monte_Carlo(atoms, calculator, space_group, f1, 'translate', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 2: # rotation Monte_Carlo(atoms, calculator, space_group, f2, 'rotation', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 3: # cell_length a Monte_Carlo(atoms, calculator, space_group, f3, 'cell_length_a', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 4: # cell_length b Monte_Carlo(atoms, calculator, space_group, f4, 'cell_length_b', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 5: # cell_length c Monte_Carlo(atoms, calculator, space_group, f5, 'cell_length_c', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 6: # cell_angle alpha Monte_Carlo(atoms, calculator, space_group, f6, 'cell_angle_alpha', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 7: # cell_angle beta Monte_Carlo(atoms, calculator, space_group, f7, 'cell_angle_beta', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1 elif random_number == 8: # cell_angle gamma Monte_Carlo(atoms, calculator, space_group, f8, 'cell_angle_gamma', counter, numb_molecules, molecule1_in_cell, MC_stpes, args.debug) counter += 1
def main(): args = parse_args() print("args", args) if args.implementation == TORCHANI: from torchani_calculator import torchani_calculator calculator = torchani_calculator(args.network_type) elif args.implementation == AES_ANI: from ani_ase import ani_ase_calculator calculator = ani_ase_calculator(args.network_type) elif args.implementation == KHAN: from khan_calculator import khan_calculator calculator = khan_calculator(args.network_type, args.khan_network, args.numb_networks) assert args.cif_file.endswith('.cif') print('debug? ', args.debug) atoms = ase_io.read(args.cif_file) numb_molecules = len(molecule_lists(atoms)) print('number of molecules: ', numb_molecules) total_number_of_molecules = numb_molecules MC_stpes = args.MC space_group = Spacegroup(args.space_group) # step size in MC f1, f2, f3, f4 = args.MC_f1_f2_f3_f4 perturbation_type = args.perturbation_type molecule1_in_cell = [] for i in range(1, atoms.get_number_of_atoms()): if atom_belong_to_mol1(i, atoms): molecule1_in_cell.append(i) # print("Space group of crystal: %s" % spacegroup.get_spacegroup(atoms)) print("initial unit cell") print(atoms.cell) print("To do Monte Carlo for %d step." % MC_stpes) print("Molecule index in ASU are: ", molecule1_in_cell) translation_stats = [] rotation_stats = [] cell_length_stats = [] cell_angle_stats = [] counter = 0 atoms_input = atoms.copy() # space_group = spacegroup.get_spacegroup(atoms) while (counter <= MC_stpes): if isinstance(perturbation_type, list): random_number = random.choice([1, 2, 3, 4]) else: random_number = perturbation_dict[perturbation_type] if random_number == 1: # translation atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f1, 'translate', counter, molecule1_in_cell, MC_stpes, args.debug) translation_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 2: # rotation atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f2, 'rotation', counter, molecule1_in_cell, MC_stpes, args.debug) rotation_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() elif random_number == 3: # cell_length atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f3, 'cell_length', counter, molecule1_in_cell, MC_stpes, args.debug) cell_length_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() else: # cell_angle atoms_input.set_calculator(calculator) ret_atoms, message = Monte_Carlo(atoms_input, calculator, space_group, f4, 'cell_angle', counter, molecule1_in_cell, MC_stpes, args.debug) cell_angle_stats.append(message) counter += 1 atoms_input = ret_atoms.copy() with open("MC_trace.json", "w") as fh: json.dump(MC_trace, fh, indent=4) print("MC trace are recorded in: MC_trace.json") print("Acceptance ratio of translation move is %f" % (countX("Accepted", translation_stats) / len(translation_stats))) print("Acceptance ratio of rotation move is %f" % (countX("Accepted", rotation_stats) / len(rotation_stats))) print("Acceptance ratio of cell length move is %f" % (countX("Accepted", cell_length_stats) / len(cell_length_stats))) print("Acceptance ratio of cell angle move is %f" % (countX("Accepted", cell_angle_stats) / len(cell_angle_stats)))
def change_cell_length(atoms, space_group): print(atoms.get_atomic_numbers()) name = get_name(atoms.get_atomic_numbers()) print(name) # to do molecule1, molecule2, molecule3, molecule4 = molecule_lists( atoms)[0], molecule_lists(atoms)[1], molecule_lists( atoms)[2], molecule_lists(atoms)[3] # [1,5,9,13,17,21,etc] print(molecule1) print(molecule2) print(molecule3) print(molecule4) scaled_positions = atoms.get_scaled_positions() #print("scaled_positions: ", scaled_positions) molecule1_scaled_positions = np.array( [scaled_positions[i] for i in molecule1]) cell_params = atoms.get_cell() #print(cell_params) #print(atoms.get_positions()) a_vector, b_vector, c_vector = cell_params[0], cell_params[1], cell_params[ 2] molecule1_vectors = np.array([ faction[0] * a_vector + faction[1] * b_vector + faction[2] * c_vector for faction in molecule1_scaled_positions ]) new_atoms = atoms.copy() new_atoms.set_cell(cell_params + np.array([[1, 0, 0], [0, 1, 0], [0.1, 0, 1]]), scale_atoms=False) new_cell_params = new_atoms.get_cell() print("new_cell_params: ", new_cell_params) new_a_vector, new_b_vector, new_c_vector = new_cell_params[ 0], new_cell_params[1], new_cell_params[2] new_vectors = [] for v in molecule1_vectors: Va = np.dot( np.cross(new_b_vector, new_c_vector) / np.dot(new_a_vector, np.cross(new_b_vector, new_c_vector)), v) Vb = np.dot( np.cross(new_c_vector, new_a_vector) / np.dot(new_b_vector, np.cross(new_c_vector, new_a_vector)), v) Vc = np.dot( np.cross(new_a_vector, new_b_vector) / np.dot(new_c_vector, np.cross(new_a_vector, new_b_vector)), v) new_vectors.append([Va, Vb, Vc]) new_sclaed_positions = np.array(new_vectors) print("get_symop(): ", space_group.get_symop()) sites = [] for kind, pos in enumerate(new_sclaed_positions): for rot, trans in space_group.get_symop(): site = np.dot(rot, pos) + trans sites.append(site) print(np.array(sites)) new_positions = np.array([ faction[0] * new_a_vector + faction[1] * new_b_vector + faction[2] * new_c_vector for faction in sites ]) print(new_positions) #wire = Atoms('', # positions=[[0, L / 2, L / 2]], # cell=[d, L, L], # pbc=[1, 0, 0]) writer = Atoms(name, positions=new_positions, cell=new_atoms.get_cell(), pbc=[1, 1, 1]) #final_scaled_positions = get_equivalent_sites(new_sclaed_positions, space_group) #print("final_scaled_positions: ", final_scaled_positions) #new_atoms.set_scaled_positions(final_scaled_positions) for i in molecule1: print( writer.get_distances(i, molecule1) - atoms.get_distances(i, molecule1)) #print(atoms.get_distance(24,36, mic=False, vector=True)) #print(new_atoms.get_distance(24,36, mic=False, vector=True)) print(writer.get_cell()) return writer
ret_atoms_translate = generate_translate_frame(ret_atoms_rotation, molecule1_atoms_index, space_group, 2.0) print("after translation ", molecule_lists(ret_atoms_translate)) ret_atoms = ret_atoms_translate.copy() return ret_atoms if __name__ == "__main__": print("runing main function for debugging...") atoms = ase_io.read(sys.argv[1]) spacegroup_number = sys.argv[2] molecule1_atoms_index = molecule_lists(atoms)[0] print(molecule_lists(atoms)) print("molecule1_atoms_index: ", molecule1_atoms_index) if spacegroup_number: space_group = Spacegroup(int(spacegroup_number)) else: space_group = spacegroup.get_spacegroup(atoms) print("before perturbation: ", space_group) # HY this is tests for perturb functions. #generate_translate_frame(atoms, molecule1_atoms_index, space_group, 0.05) #generate_rotation_frame(atoms, molecule1_atoms_index, space_group, 0.05) #generate_cell_length_a_frame(atoms, molecule1_atoms_index, space_group, 10.0) #generate_cell_length_b_frame(atoms, molecule1_atoms_index, space_group, 10.0) #generate_cell_length_c_frame(atoms, molecule1_atoms_index, space_group, 1.0) generate_cell_angle_beta_frame(atoms, molecule1_atoms_index, space_group,